1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004, 2008-2010 VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
8 * Andy Gatward <a.j.gatward@reading.ac.uk>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
41 #include <bitstream/mpeg/ts.h>
42 #include <bitstream/ietf/rtp.h>
44 /*****************************************************************************
46 *****************************************************************************/
49 struct packet_t
*p_next
;
53 /* PRIVATE - this MUST be at the end of the structure: */
54 block_t
*p_blocks
; /* actually an array of pointers */
57 static uint8_t p_pad_ts
[TS_SIZE
] = {
58 0x47, 0x1f, 0xff, 0x10, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
61 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
62 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
63 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
64 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
68 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
70 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
76 /*****************************************************************************
77 * output_Create : create and insert the output_t structure
78 *****************************************************************************/
79 output_t
*output_Create( const output_config_t
*p_config
)
82 output_t
*p_output
= NULL
;
84 for ( i
= 0; i
< i_nb_outputs
; i
++ )
86 if ( !( pp_outputs
[i
]->config
.i_config
& OUTPUT_VALID
) )
88 p_output
= pp_outputs
[i
];
93 if ( p_output
== NULL
)
95 p_output
= malloc( sizeof(output_t
) );
97 pp_outputs
= realloc( pp_outputs
, i_nb_outputs
* sizeof(output_t
*) );
98 pp_outputs
[i
] = p_output
;
101 if ( output_Init( p_output
, p_config
) < 0 )
107 /*****************************************************************************
108 * output_Init : set up the output initial config
109 *****************************************************************************/
110 int output_Init( output_t
*p_output
, const output_config_t
*p_config
)
112 socklen_t i_sockaddr_len
= (p_config
->i_family
== AF_INET
) ?
113 sizeof(struct sockaddr_in
) :
114 sizeof(struct sockaddr_in6
);
116 memset( p_output
, 0, sizeof(output_t
) );
117 config_Init( &p_output
->config
);
119 /* Init run-time values */
120 p_output
->p_packets
= p_output
->p_last_packet
= NULL
;
121 p_output
->i_cc
= rand() & 0xffff;
122 p_output
->i_pat_cc
= rand() & 0xf;
123 p_output
->i_pmt_cc
= rand() & 0xf;
124 p_output
->i_nit_cc
= rand() & 0xf;
125 p_output
->i_sdt_cc
= rand() & 0xf;
126 p_output
->i_eit_cc
= rand() & 0xf;
127 p_output
->i_pat_version
= rand() & 0xff;
128 p_output
->i_pmt_version
= rand() & 0xff;
129 p_output
->i_nit_version
= rand() & 0xff;
130 p_output
->i_sdt_version
= rand() & 0xff;
131 p_output
->p_pat_section
= NULL
;
132 p_output
->p_pmt_section
= NULL
;
133 p_output
->p_nit_section
= NULL
;
134 p_output
->p_sdt_section
= NULL
;
135 p_output
->p_eit_ts_buffer
= NULL
;
137 p_output
->i_tsid
= rand() & 0xffff;
139 /* Init socket-related fields */
140 p_output
->config
.i_family
= p_config
->i_family
;
141 memcpy( &p_output
->config
.connect_addr
, &p_config
->connect_addr
,
142 sizeof(struct sockaddr_storage
) );
143 memcpy( &p_output
->config
.bind_addr
, &p_config
->bind_addr
,
144 sizeof(struct sockaddr_storage
) );
145 p_output
->config
.i_if_index_v6
= p_config
->i_if_index_v6
;
147 p_output
->i_handle
= socket( p_config
->i_family
, SOCK_DGRAM
, IPPROTO_UDP
);
148 if ( p_output
->i_handle
< 0 )
150 msg_Err( NULL
, "couldn't create socket (%s)", strerror(errno
) );
151 p_output
->config
.i_config
&= ~OUTPUT_VALID
;
155 if ( p_config
->bind_addr
.ss_family
!= AF_UNSPEC
)
157 if ( bind( p_output
->i_handle
, (struct sockaddr
*)&p_config
->bind_addr
,
158 i_sockaddr_len
) < 0 )
159 msg_Warn( NULL
, "couldn't bind socket (%s)", strerror(errno
) );
161 if ( p_config
->i_family
== AF_INET
)
163 struct sockaddr_in
*p_connect_addr
=
164 (struct sockaddr_in
*)&p_output
->config
.connect_addr
;
165 struct sockaddr_in
*p_bind_addr
=
166 (struct sockaddr_in
*)&p_output
->config
.bind_addr
;
168 if ( IN_MULTICAST( ntohl( p_connect_addr
->sin_addr
.s_addr
) ) )
169 setsockopt( p_output
->i_handle
, IPPROTO_IP
, IP_MULTICAST_IF
,
170 (void *)&p_bind_addr
->sin_addr
.s_addr
,
171 sizeof(p_bind_addr
->sin_addr
.s_addr
) );
175 if ( p_config
->i_family
== AF_INET6
&& p_config
->i_if_index_v6
!= -1 )
177 struct sockaddr_in6
*p_addr
=
178 (struct sockaddr_in6
*)&p_output
->config
.connect_addr
;
179 if ( IN6_IS_ADDR_MULTICAST( p_addr
->sin6_addr
.s6_addr
) )
180 setsockopt( p_output
->i_handle
, IPPROTO_IPV6
,
181 IPV6_MULTICAST_IF
, (void *)&p_config
->i_if_index_v6
,
182 sizeof(p_config
->i_if_index_v6
) );
185 if ( connect( p_output
->i_handle
,
186 (struct sockaddr
*)&p_output
->config
.connect_addr
,
187 i_sockaddr_len
) < 0 )
189 msg_Err( NULL
, "couldn't connect socket (%s)", strerror(errno
) );
190 close( p_output
->i_handle
);
191 p_output
->config
.i_config
&= ~OUTPUT_VALID
;
195 p_output
->config
.i_config
|= OUTPUT_VALID
;
200 /*****************************************************************************
202 *****************************************************************************/
203 void output_Close( output_t
*p_output
)
205 packet_t
*p_packet
= p_output
->p_packets
;
206 while ( p_packet
!= NULL
)
210 for ( i
= 0; i
< p_packet
->i_depth
; i
++ )
212 p_packet
->pp_blocks
[i
]->i_refcount
--;
213 if ( !p_packet
->pp_blocks
[i
]->i_refcount
)
214 block_Delete( p_packet
->pp_blocks
[i
] );
216 p_output
->p_packets
= p_packet
->p_next
;
218 p_packet
= p_output
->p_packets
;
221 p_output
->p_packets
= p_output
->p_last_packet
= NULL
;
222 free( p_output
->p_pat_section
);
223 free( p_output
->p_pmt_section
);
224 free( p_output
->p_nit_section
);
225 free( p_output
->p_sdt_section
);
226 free( p_output
->p_eit_ts_buffer
);
227 p_output
->config
.i_config
&= ~OUTPUT_VALID
;
229 close( p_output
->i_handle
);
231 config_Free( &p_output
->config
);
234 /*****************************************************************************
236 *****************************************************************************/
237 static int output_BlockCount( output_t
*p_output
)
239 int i_mtu
= p_output
->config
.i_mtu
;
240 if ( !(p_output
->config
.i_config
& OUTPUT_UDP
) )
241 i_mtu
-= RTP_HEADER_SIZE
;
242 return i_mtu
/ TS_SIZE
;
245 /*****************************************************************************
247 *****************************************************************************/
248 static void output_Flush( output_t
*p_output
)
250 packet_t
*p_packet
= p_output
->p_packets
;
251 int i_block_cnt
= output_BlockCount( p_output
);
252 struct iovec p_iov
[i_block_cnt
+ 1];
253 uint8_t p_rtp_hdr
[RTP_HEADER_SIZE
];
256 if ( !(p_output
->config
.i_config
& OUTPUT_UDP
) )
258 p_iov
[0].iov_base
= p_rtp_hdr
;
259 p_iov
[0].iov_len
= sizeof(p_rtp_hdr
);
261 rtp_set_hdr( p_rtp_hdr
);
262 rtp_set_type( p_rtp_hdr
, RTP_TYPE_TS
);
263 rtp_set_cc( p_rtp_hdr
, p_output
->i_cc
++ );
264 rtp_set_timestamp( p_rtp_hdr
,
265 p_output
->i_ref_timestamp
266 + (p_packet
->i_dts
- p_output
->i_ref_wallclock
)
268 rtp_set_ssrc( p_rtp_hdr
, p_output
->config
.pi_ssrc
);
275 for ( i_block
= 0; i_block
< p_packet
->i_depth
; i_block
++ )
277 p_iov
[i_iov
].iov_base
= p_packet
->pp_blocks
[i_block
]->p_ts
;
278 p_iov
[i_iov
].iov_len
= TS_SIZE
;
282 for ( ; i_block
< i_block_cnt
; i_block
++ )
284 p_iov
[i_iov
].iov_base
= p_pad_ts
;
285 p_iov
[i_iov
].iov_len
= TS_SIZE
;
289 if ( writev( p_output
->i_handle
, p_iov
, i_iov
) < 0 )
291 msg_Err( NULL
, "couldn't writev to %s (%s)",
292 p_output
->config
.psz_displayname
, strerror(errno
) );
294 /* Update the wallclock because writev() can take some time. */
295 i_wallclock
= mdate();
297 for ( i_block
= 0; i_block
< p_packet
->i_depth
; i_block
++ )
299 p_packet
->pp_blocks
[i_block
]->i_refcount
--;
300 if ( !p_packet
->pp_blocks
[i_block
]->i_refcount
)
301 block_Delete( p_packet
->pp_blocks
[i_block
] );
303 p_output
->p_packets
= p_packet
->p_next
;
305 if ( p_output
->p_packets
== NULL
)
306 p_output
->p_last_packet
= NULL
;
309 /*****************************************************************************
310 * output_Put : called from demux
311 *****************************************************************************/
312 void output_Put( output_t
*p_output
, block_t
*p_block
)
314 int i_block_cnt
= output_BlockCount( p_output
);
317 p_block
->i_refcount
++;
319 if ( p_output
->p_last_packet
!= NULL
320 && p_output
->p_last_packet
->i_depth
< i_block_cnt
321 && p_output
->p_last_packet
->i_dts
+ p_output
->config
.i_max_retention
324 p_packet
= p_output
->p_last_packet
;
325 if ( ts_has_adaptation( p_block
->p_ts
)
326 && ts_get_adaptation( p_block
->p_ts
)
327 && tsaf_has_pcr( p_block
->p_ts
) )
328 p_packet
->i_dts
= p_block
->i_dts
;
332 /* This isn't the cleanest allocation of the world. */
333 p_packet
= malloc( sizeof(packet_t
)
334 + (i_block_cnt
- 1) * sizeof(block_t
*) );
335 p_packet
->pp_blocks
= &p_packet
->p_blocks
;
336 p_packet
->i_depth
= 0;
337 p_packet
->p_next
= NULL
;
338 p_packet
->i_dts
= p_block
->i_dts
;
339 if ( p_output
->p_last_packet
!= NULL
)
340 p_output
->p_last_packet
->p_next
= p_packet
;
342 p_output
->p_packets
= p_packet
;
343 p_output
->p_last_packet
= p_packet
;
346 p_packet
->pp_blocks
[p_packet
->i_depth
] = p_block
;
350 /*****************************************************************************
351 * output_Send : called from main to flush the queues when needed
352 *****************************************************************************/
353 mtime_t
output_Send( void )
355 mtime_t i_earliest_dts
= -1;
358 if ( output_dup
.config
.i_config
& OUTPUT_VALID
)
360 while ( output_dup
.p_packets
!= NULL
361 && output_dup
.p_packets
->i_dts
362 + output_dup
.config
.i_output_latency
<= i_wallclock
)
363 output_Flush( &output_dup
);
365 if ( output_dup
.p_packets
!= NULL
)
366 i_earliest_dts
= output_dup
.p_packets
->i_dts
;
369 for ( i
= 0; i
< i_nb_outputs
; i
++ )
371 output_t
*p_output
= pp_outputs
[i
];
372 if ( !( p_output
->config
.i_config
& OUTPUT_VALID
) )
375 while ( p_output
->p_packets
!= NULL
376 && p_output
->p_packets
->i_dts
377 + p_output
->config
.i_output_latency
<= i_wallclock
)
378 output_Flush( p_output
);
380 if ( p_output
->p_packets
!= NULL
381 && (p_output
->p_packets
->i_dts
382 + p_output
->config
.i_output_latency
< i_earliest_dts
383 || i_earliest_dts
== -1) )
384 i_earliest_dts
= p_output
->p_packets
->i_dts
385 + p_output
->config
.i_output_latency
;
388 return i_earliest_dts
== -1 ? -1 : i_earliest_dts
- i_wallclock
;
391 /*****************************************************************************
392 * output_Find : find an existing output from a given output_config_t
393 *****************************************************************************/
394 output_t
*output_Find( const output_config_t
*p_config
)
396 socklen_t i_sockaddr_len
= (p_config
->i_family
== AF_INET
) ?
397 sizeof(struct sockaddr_in
) :
398 sizeof(struct sockaddr_in6
);
401 for ( i
= 0; i
< i_nb_outputs
; i
++ )
403 output_t
*p_output
= pp_outputs
[i
];
405 if ( !(p_output
->config
.i_config
& OUTPUT_VALID
) ) continue;
407 if ( p_config
->i_family
!= p_output
->config
.i_family
||
408 memcmp( &p_config
->connect_addr
, &p_output
->config
.connect_addr
,
410 memcmp( &p_config
->bind_addr
, &p_output
->config
.bind_addr
,
414 if ( p_config
->i_family
== AF_INET6
&&
415 p_config
->i_if_index_v6
!= p_output
->config
.i_if_index_v6
)
424 /*****************************************************************************
425 * output_Change : get changes from a new output_config_t
426 *****************************************************************************/
427 void output_Change( output_t
*p_output
, const output_config_t
*p_config
)
429 memcpy( p_output
->config
.pi_ssrc
, p_config
->pi_ssrc
, 4 * sizeof(uint8_t) );
430 p_output
->config
.i_output_latency
= p_config
->i_output_latency
;
431 p_output
->config
.i_max_retention
= p_config
->i_max_retention
;
433 if ( p_output
->config
.i_ttl
!= p_config
->i_ttl
)
435 if ( p_output
->config
.i_family
== AF_INET6
)
437 struct sockaddr_in6
*p_addr
=
438 (struct sockaddr_in6
*)&p_output
->config
.connect_addr
;
439 if ( IN6_IS_ADDR_MULTICAST( p_addr
->sin6_addr
.s6_addr
) )
440 setsockopt( p_output
->i_handle
, IPPROTO_IPV6
,
441 IPV6_MULTICAST_HOPS
, (void *)&p_config
->i_ttl
,
442 sizeof(p_config
->i_ttl
) );
446 struct sockaddr_in
*p_addr
=
447 (struct sockaddr_in
*)&p_output
->config
.connect_addr
;
448 if ( IN_MULTICAST( ntohl( p_addr
->sin_addr
.s_addr
) ) )
449 setsockopt( p_output
->i_handle
, IPPROTO_IP
, IP_MULTICAST_TTL
,
450 (void *)&p_config
->i_ttl
, sizeof(p_config
->i_ttl
) );
452 p_output
->config
.i_ttl
= p_config
->i_ttl
;
455 if ( p_output
->config
.i_tos
!= p_config
->i_tos
)
457 if ( p_output
->config
.i_family
== AF_INET
)
458 setsockopt( p_output
->i_handle
, IPPROTO_IP
, IP_TOS
,
459 (void *)&p_config
->i_tos
, sizeof(p_config
->i_tos
) );
460 p_output
->config
.i_tos
= p_config
->i_tos
;
463 if ( p_output
->config
.i_mtu
!= p_config
->i_mtu
464 || ((p_output
->config
.i_config
^ p_config
->i_config
) & OUTPUT_UDP
) )
467 packet_t
*p_packet
= p_output
->p_last_packet
;
468 p_output
->config
.i_config
&= ~OUTPUT_UDP
;
469 p_output
->config
.i_config
|= p_config
->i_config
& OUTPUT_UDP
;
470 p_output
->config
.i_mtu
= p_config
->i_mtu
;
472 i_block_cnt
= output_BlockCount( p_output
);
473 if ( p_packet
!= NULL
&& p_packet
->i_depth
< i_block_cnt
)
475 p_packet
= realloc( p_packet
, sizeof(packet_t
*)
476 + (i_block_cnt
- 1) * sizeof(block_t
*) );
477 p_packet
->pp_blocks
= &p_packet
->p_blocks
;