Skip to content

Commit

Permalink
Merge pull request #33 from freddy36/rtp-out
Browse files Browse the repository at this point in the history
RTP output support
  • Loading branch information
gfto authored Mar 13, 2024
2 parents be2845a + d8eb8f5 commit 634791e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 3 deletions.
3 changes: 3 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ This is useful for hardware modulators that require correct PCR values
(most cheap modulators do, so always use "-m 3" with them).
mptsd was tested and found to be working ok with Dektec DTE-3114 & HiDes UT-100C.

To enable RTP output instead of plain UDP for network streams,
specify the SSRC identifier via the -s flag (must be != 0).

Development
===========
The development is tracked using git. The repository is hosted at github
Expand Down
11 changes: 9 additions & 2 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ static void show_usage(void) {
puts("\t-P ip\t\tOutput udp port (default: 5000)");
puts("\t-o ip\t\tOutput interface address (default: 0.0.0.0)");
puts("\t-t ttl\t\tSet multicast ttl (default: 1)");
puts("\t-s SSRC\t\tEnables RTP (default: disabled)");
puts("");
puts("\t-B Mbps\t\tOutput bitrate in Mbps (default: 38.00)");
puts("\t-m mode\t\tPCR mode (modes list bellow)");
Expand All @@ -453,13 +454,15 @@ void config_load(CONFIG *conf, int argc, char **argv) {

conf->multicast_ttl = 1;
conf->output->out_port = 5000;
conf->output->rtp_sequence_number = 1;
conf->output->rtp_ssrc = 0;
conf->output_bitrate = 38;
conf->logport = 514;
conf->server_port = 0;
conf->server_socket = -1;
conf->write_output_network = 1;

while ((j = getopt(argc, argv, "i:b:p:g:c:n:e:d:t:o:O:P:l:L:B:m:qDHhEWN")) != -1) {
while ((j = getopt(argc, argv, "i:b:p:g:c:n:e:d:t:o:O:P:l:L:B:m:s:qDHhEWN")) != -1) {
switch (j) {
case 'i':
conf->ident = strdup(optarg);
Expand Down Expand Up @@ -511,6 +514,9 @@ void config_load(CONFIG *conf, int argc, char **argv) {
exit(1);
}
break;
case 's':
conf->output->rtp_ssrc = strtoul(optarg, NULL, 10);
break;
case 'm':
conf->pcr_mode = atoi(optarg);
if (conf->pcr_mode < 0 || conf->pcr_mode > 4)
Expand Down Expand Up @@ -595,10 +601,11 @@ void config_load(CONFIG *conf, int argc, char **argv) {
printf("\tGlobal config : %s\n", conf->global_conf);
printf("\tChannels config : %s\n", conf->channels_conf);
printf("\tNIT config : %s\n", conf->nit_conf);
printf("\tOutput addr : udp://%s:%d\n", inet_ntoa(conf->output->out_host), conf->output->out_port);
printf("\tOutput addr : %s://%s:%d\n", (conf->output->rtp_ssrc != 0 ? "rtp" : "udp"), inet_ntoa(conf->output->out_host), conf->output->out_port);
if (conf->output_intf.s_addr)
printf("\tOutput iface addr : %s\n", inet_ntoa(conf->output_intf));
printf("\tMulticast ttl : %d\n", conf->multicast_ttl);
printf("\tRTP SSRC : %u\n", conf->output->rtp_ssrc);
if (conf->syslog_active) {
printf("\tSyslog host : %s\n", conf->loghost);
printf("\tSyslog port : %d\n", conf->logport);
Expand Down
3 changes: 3 additions & 0 deletions data.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ typedef struct {
uint64_t last_org_pcr[8193]; // Last PCR value indexed by PID x
uint64_t last_pcr[8193]; // Last PCR value indexed by PID x
uint64_t last_traffic[8193]; // Last traffic when PCR with PID x was seen

uint16_t rtp_sequence_number; // RTP sequence number
uint32_t rtp_ssrc; // use RTP is != 0
} OUTPUT;

typedef struct {
Expand Down
57 changes: 56 additions & 1 deletion output_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ void ts_frame_process(CONFIG *conf, OUTPUT *o, uint8_t *data) {
}
}


// write plain UDP packets
ssize_t ts_frame_write(OUTPUT *o, uint8_t *data) {
ssize_t written;
written = fdwrite(o->out_sock, (char *)data, FRAME_PACKET_SIZE);
Expand All @@ -114,6 +116,55 @@ ssize_t ts_frame_write(OUTPUT *o, uint8_t *data) {
return written;
}


// write RTP packets
ssize_t ts_frame_write_rtp(OUTPUT *o, uint8_t *data) {
ssize_t written;
const size_t write_len = FRAME_PACKET_SIZE + RTP_HEADER_SIZE;
uint8_t rtp_buffer[write_len];

rtp_buffer[0] = (((2 & 0x03) << 6) // version
| ((0 & 0x01) << 5) // padding
| ((0 & 0x01) << 4) // extension
| ((0 & 0x0F) << 0)); // cc

rtp_buffer[1] = ( ((0 & 0x01) << 7) // Marker
| ((33 & 0x7F) << 0) ); // Payload type: MPEG-II transport streams (33)

// sequence number
uint16_t seq = htons(o->rtp_sequence_number);
memcpy (&rtp_buffer[2], &seq, 2);

// timestamp
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t time = ts.tv_sec * 1000000ll + ts.tv_nsec / 1000;
uint32_t timestamp_value = (uint32_t) (90000 * (time/1000000ll))+(9*(time%1000000ll))/100; // 90 kHz Clock
uint32_t timestamp = htonl(timestamp_value);
memcpy (&rtp_buffer[4], &timestamp, 4);

// SSRC
uint32_t ssrc = htonl(o->rtp_ssrc);
memcpy (&rtp_buffer[8], &ssrc, 4);

// copy payload
memcpy(&rtp_buffer[12], data, FRAME_PACKET_SIZE);

written = fdwrite(o->out_sock, (char *)rtp_buffer, write_len);
if (written >= RTP_HEADER_SIZE) {
written -= RTP_HEADER_SIZE;
o->traffic += written;
o->traffic_period += written;
}

if (o->ofd)
write(o->ofd, data, FRAME_PACKET_SIZE);

o->rtp_sequence_number++; // increment RTP sequence number

return written;
}

void * output_handle_write(void *_config) {
CONFIG *conf = _config;
OUTPUT *o = conf->output;
Expand Down Expand Up @@ -169,7 +220,11 @@ void * output_handle_write(void *_config) {
long sleep_interval = conf->output_tmout;
uint8_t *ts_frame = curbuf->buf + curbuf->written;
ts_frame_process(conf, o, ts_frame); // Fix PCR and count NULL packets
written += ts_frame_write(o, ts_frame); // Write packet to network/file
if (o->rtp_ssrc != 0) {
written += ts_frame_write_rtp(o, ts_frame); // Write RTP packet to network/file
} else {
written += ts_frame_write(o, ts_frame); // Write plain UDP packet to network/file
}
curbuf->written += FRAME_PACKET_SIZE;
if (packets_written) {
time_taken = timeval_diff_usec(&start_write_ts, &used_ts);
Expand Down

0 comments on commit 634791e

Please sign in to comment.