68 const char *address_2,
unsigned int port1,
69 unsigned int port2,
long mtu)
79 if ((connection->
rx_socket_1 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
80 fprintf(stderr,
"Error creating first receiving socket");
84 if ((connection->
rx_socket_2 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
85 fprintf(stderr,
"Error creating second receiving socket");
89 if (address_1 != NULL)
91 struct hostent *target = gethostbyname(address_1);
93 printf(
"Unknown target 1");
97 connection->
peer_address_1 = *(
struct in_addr *)(
void *) target->h_addr;
102 if (address_2 != NULL)
104 struct hostent *target = gethostbyname(address_2);
105 if (target == NULL) {
106 printf(
"Unknown target 2");
110 connection->
peer_address_2 = *(
struct in_addr *)(
void *) target->h_addr;
115 struct sockaddr_in rx_address;
116 rx_address.sin_family = AF_INET;
117 rx_address.sin_addr.s_addr = htonl(INADDR_ANY);
118 rx_address.sin_port = htons(connection->
rx_port_1);
119 memset(rx_address.sin_zero,
'\0',
sizeof(rx_address.sin_zero));
121 (connection->
rx_socket_1, (
struct sockaddr *)&rx_address,
122 sizeof(rx_address)) == -1) {
123 fprintf(stderr,
"Error binding receiver to the first socket");
127 rx_address.sin_family = AF_INET;
128 rx_address.sin_addr.s_addr = htonl(INADDR_ANY);
129 rx_address.sin_port = htons(connection->
rx_port_2);
130 memset(rx_address.sin_zero,
'\0',
sizeof(rx_address.sin_zero));
132 (connection->
rx_socket_2, (
struct sockaddr *)&rx_address,
133 sizeof(rx_address)) == -1) {
134 fprintf(stderr,
"Error binding receiver to the second socket");
140 fprintf(stderr,
"Error: mtu must be > 0");
176 if (fcntl(connection->
rx_socket_1, F_SETFL, O_NONBLOCK) < 0) {
177 fprintf(stderr,
"Error setting rx_socket_1 as nonblocking\n");
181 if (fcntl(connection->
rx_socket_2, F_SETFL, O_NONBLOCK) < 0) {
182 fprintf(stderr,
"Error setting rx_socket_2 as nonblocking\n");
191 const char *address_2,
long mtu)
199 struct hostent *target_1 = gethostbyname(address_1);
200 if (target_1 == NULL) {
201 printf(
"Unknown target 1");
205 struct hostent *target_2 = gethostbyname(address_2);
206 if (target_2 == NULL) {
207 printf(
"Unknown target 2");
211 if ((connection->
tx_socket_1 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
212 fprintf(stderr,
"Error creating sending socket 1");
215 if ((connection->
tx_socket_2 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
216 fprintf(stderr,
"Error creating sending socket 2");
223 *((
struct in_addr *)(
void *) target_1->h_addr);
229 *((
struct in_addr *)(
void *) target_2->h_addr);
235 fprintf(stderr,
"Error: mtu must be > 0");
270 unsigned long buffer_length)
273 struct msghdr msg1, msg2;
282 struct iovec vector1[2];
283 struct iovec vector2[2];
286 msg1.msg_iov = (
struct iovec *) &vector1;
287 msg2.msg_iov = (
struct iovec *) &vector2;
292 msg1.msg_control = 0;
293 msg2.msg_control = 0;
294 msg1.msg_controllen = 0;
295 msg2.msg_controllen = 0;
300 ihdtv_packet packet_1;
301 ihdtv_packet packet_2;
306 packet_1.stream_id = 0;
307 packet_2.stream_id = 1;
309 unsigned int offset_absolut_1 = 0;
312 unsigned int packet_relative_offset = 0;
316 packet_1.offset = packet_relative_offset;
317 vector1[0].iov_base = &packet_1;
318 vector1[0].iov_len = 16;
319 vector1[1].iov_base =
vf_get_tile(tx_frame, 0)->
data + offset_absolut_1;
321 if (sendmsg(connection->
tx_socket_1, &msg1, 0) == -1) {
322 perror(
"Sending data to address 1");
326 packet_2.offset = packet_relative_offset;
327 vector2[0].iov_base = &packet_2;
328 vector2[0].iov_len = 16;
329 vector2[1].iov_base =
vf_get_tile(tx_frame, 0)->
data + offset_absolut_2;
331 if (sendmsg(connection->
tx_socket_2, &msg2, 0) == -1) {
332 perror(
"Sending data to address 2");
336 ++packet_relative_offset;
341 packet_1.offset = packet_relative_offset;
342 vector1[0].iov_base = &packet_1;
343 vector1[0].iov_len = 16;
344 vector1[1].iov_base =
vf_get_tile(tx_frame, 0)->
data + offset_absolut_1;
346 if (sendmsg(connection->
tx_socket_1, &msg1, 0) == -1) {
347 perror(
"Sending data to address 1");
351 packet_2.offset = packet_relative_offset;
352 vector2[0].iov_base = &packet_2;
353 vector2[0].iov_len = 16;
354 vector2[1].iov_base =
vf_get_tile(tx_frame, 0)->
data + offset_absolut_2;
356 if (sendmsg(connection->
tx_socket_2, &msg2, 0) == -1) {
357 perror(
"Sending data to address 2");
366inline static int packet_to_buffer(
const ihdtv_connection * connection,
char *buffer,
const unsigned long buffer_length,
const ihdtv_packet * packet,
const int packet_length)
368 if (buffer_length < (
unsigned long int)
370 (packet_length - 16)))
373 if (packet->stream_id == 0) {
376 packet->data, packet_length - 16);
380 if (packet->stream_id == 1) {
393 const unsigned long buffer_length)
395 int packets_number = 0;
399 struct sockaddr_in sender_address;
400 socklen_t sender_address_length =
sizeof(sender_address);
404 if (buffer == NULL) {
406 "iHDTV receiver: buffer is empty, not receiving.\n");
424 recvfrom(connection->
rx_socket_1, &packet,
sizeof(packet),
425 0, (
struct sockaddr *)&sender_address,
426 &sender_address_length)) > -1) {
429 sender_address.sin_addr.s_addr)
431 sender_address.sin_addr.s_addr)) {
432 if (packet.stream_id == 0 || packet.stream_id == 1) {
446 if (packet.frame_number ==
463 }
else if (errno != EWOULDBLOCK) {
464 fprintf(stderr,
"Error receiving packet\n");
469 recvfrom(connection->
rx_socket_2, &packet,
sizeof(packet),
470 0, (
struct sockaddr *)&sender_address,
471 &sender_address_length)) > -1) {
474 sender_address.sin_addr.s_addr)
476 sender_address.sin_addr.s_addr)) {
477 if (packet.stream_id == 0 || packet.stream_id == 1) {
490 if (packet.frame_number ==
507 }
else if (errno != EWOULDBLOCK) {
508 fprintf(stderr,
"Error receiving packet\n");
int ihdtv_receive(ihdtv_connection *connection, char *buffer, const unsigned long buffer_length)
int ihdtv_init_rx_session(ihdtv_connection *connection, const char *address_1, const char *address_2, unsigned int port1, unsigned int port2, long mtu)
int ihdtv_init_tx_session(ihdtv_connection *connection, const char *address_1, const char *address_2, long mtu)
int ihdtv_send(ihdtv_connection *connection, struct video_frame *tx_frame, unsigned long buffer_length)
static int packet_to_buffer(const ihdtv_connection *connection, char *buffer, const unsigned long buffer_length, const ihdtv_packet *packet, const int packet_length)
unsigned int video_packets_per_frame
unsigned long bytes_per_frame
unsigned int ppacket_size
struct sockaddr_in target_sockaddress_1
long video_data_per_packet
struct sockaddr_in target_sockaddress_2
struct in_addr peer_address_1
struct in_addr peer_address_2
unsigned long bytes_per_half_frame
unsigned int video_packets_per_half_frame
long video_data_per_last_packet
char * data
Raw tile data. Pointer must be at least 4B aligned.
Struct video_frame represents a video frame and contains video description.
This is an umbrella header for video functions.
struct tile * vf_get_tile(struct video_frame *buf, int pos)
Returns pointer to n-th tile from video frame Equivalent to &video_frame::tiles[pos].