Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

xdvshow-rtp.c File Reference

#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <assert.h>
#include <libdv/dv_types.h>
#include <semaphore.h>
#include "RTP.h"
#include "xdvshow-const.h"
#include "xdvshow-shm.h"
#include "xdvshow-flags.h"
#include "xdvshow-rtp.h"
#include "xdvshow-defs.h"

Include dependency graph for xdvshow-rtp.c:

Include dependency graph

Go to the source code of this file.

Functions

int _xdvshow_prepare_socket __P ((struct xdvshow_rtp_param *))
int _xdvshow_recv_dvrtp __P ((void))
void * xdvshow_ping_reflector (void *data)
 periodically sends a dummy packet to the packet reflector.

void * xdvshow_prepare_rtp (void *data)
 Public function that handles the input from a network.

int _xdvshow_prepare_socket (struct xdvshow_rtp_param *rtp_param)
 creates a communication socket and returns a descriptor.

int _multicast_str2addr (struct xdvshow_rtp_param *rtp_param)
 converts the multicast address into binary data in network byte order.

int _chk_multicast_addr (struct xdvshow_rtp_param *rtp_param)
 checks if the given address is a correct multicast address.

int _chk_multicast_family (struct xdvshow_rtp_param *rtp_param)
 checks the multicast address family.

int _multicast_join (struct xdvshow_rtp_param *rtp_param)
 is an internal function that joins mlticast group given by its address.

int _xdvshow_prepare_multicast (struct xdvshow_rtp_param *rtp_param)
 converts the given address, checks if the address is correct and then joins the multicast group.

int _xdvshow_recv_dvrtp ()
 internal function that acquires the DV stream from a network.


Function Documentation

int _xdvshow_recv_dvrtp __P (void)   )  [static]
 

int _xdvshow_prepare_multicast __P (struct xdvshow_rtp_param *)   )  [static]
 

int _chk_multicast_addr struct xdvshow_rtp_param rtp_param  )  [static]
 

checks if the given address is a correct multicast address.

Parameters:
*rtp_param (struct xdvshow_rtp_param)
Returns:
1 on success. -1 if the function fails for some reason.

Definition at line 265 of file xdvshow-rtp.c.

References xdvshow_rtp_param::multi_addr_str, xdvshow_rtp_param::multi_s_addr, and rtp_param.

Referenced by _xdvshow_prepare_multicast().

00266 { 00267 struct sockaddr_in *s_in = (struct sockaddr_in *)&rtp_param->multi_s_addr; 00268 #ifdef ENABLE_INET6 00269 struct sockaddr_in6 *s6_in = (struct sockaddr_in6 *)&rtp_param->multi_s_addr; 00270 #endif /* ENABLE_INET6 */ 00271 00272 switch (rtp_param->multi_s_addr.ss_family) { 00273 case AF_INET: 00274 if (!IN_MULTICAST(ntohl(s_in->sin_addr.s_addr))) { 00275 printf("ERROR : [%s] is not multicast address\n", 00276 rtp_param->multi_addr_str); 00277 return(-1); 00278 } 00279 break; 00280 00281 #ifdef ENABLE_INET6 00282 case AF_INET6: 00283 if (!IN6_IS_ADDR_MULTICAST(&s6_in->sin6_addr)) { 00284 printf("ERROR : [%s] is not multicast address\n", 00285 rtp_param->multi_addr_str); 00286 return(-1); 00287 } 00288 break; 00289 #endif /* ENABLE_INET6 */ 00290 00291 default: 00292 printf("ERROR : unknown multicast addr family : %d\n", 00293 rtp_param->multi_s_addr.ss_family); 00294 return(-1); 00295 break; 00296 } 00297 00298 return(1); 00299 }

int _chk_multicast_family struct xdvshow_rtp_param rtp_param  )  [static]
 

checks the multicast address family.

Parameters:
*rtp_param (struct xdvshow_rtp_param)
Returns:
1 on success. -1 if the function fails for some reason.

Definition at line 309 of file xdvshow-rtp.c.

References xdvshow_rtp_param::multi_s_addr, rtp_param, and xdvshow_rtp_param::s_addr.

Referenced by _xdvshow_prepare_multicast().

00310 { 00311 if (rtp_param->s_addr.ss_family != 00312 rtp_param->multi_s_addr.ss_family) { 00313 printf("Protocol family of DV/RTP socket and multicast join address mismatch\n"); 00314 00315 switch (rtp_param->s_addr.ss_family) { 00316 case AF_INET: 00317 printf("DV/RTP socket family : IPv4 (AF_INET)\n"); 00318 break; 00319 00320 #ifdef ENABLE_INET6 00321 case AF_INET6: 00322 printf("DV/RTP socket family : IPv6 (AF_INET6)\n"); 00323 break; 00324 #endif /* ENABLE_INET6 */ 00325 00326 default: 00327 break; 00328 } 00329 switch (rtp_param->multi_s_addr.ss_family) { 00330 case AF_INET: 00331 printf("multicast join address : IPv4 (AF_INET)\n"); 00332 break; 00333 00334 #ifdef ENABLE_INET6 00335 case AF_INET6: 00336 printf("multicast join address : IPv6 (AF_INET6)\n"); 00337 break; 00338 #endif /* ENABLE_INET6 */ 00339 00340 default: 00341 break; 00342 } 00343 00344 return(-1); 00345 } 00346 00347 return(1); 00348 }

int _multicast_join struct xdvshow_rtp_param rtp_param  )  [static]
 

is an internal function that joins mlticast group given by its address.

Parameters:
*rtp_param (struct xdvshow_rtp_param)
Returns:
1 on success. -1 if the function fails for some reason.

Definition at line 357 of file xdvshow-rtp.c.

References _xdvshow_shm, xdvshow_rtp_param::multi_ifname, xdvshow_rtp_param::multi_s_addr, rtp_param, xdvshow_rtp_param::s_addr, and __xdvshow_shm::soc.

Referenced by _xdvshow_prepare_multicast().

00358 { 00359 struct ip_mreq mreq; 00360 struct sockaddr_in *s_in = (struct sockaddr_in *)&rtp_param->multi_s_addr; 00361 struct sockaddr_in *base_s_in = (struct sockaddr_in *)&rtp_param->s_addr; 00362 #ifdef ENABLE_INET6 00363 struct ipv6_mreq mreq6; 00364 struct sockaddr_in6 *s6_in = (struct sockaddr_in6 *)&rtp_param->multi_s_addr; 00365 00366 memset(&mreq6, 0, sizeof(mreq6)); 00367 #endif /* ENABLE_INET6 */ 00368 00369 memset(&mreq, 0, sizeof(mreq)); 00370 00371 switch (rtp_param->multi_s_addr.ss_family) { 00372 case AF_INET: 00373 mreq.imr_multiaddr.s_addr = s_in->sin_addr.s_addr; 00374 mreq.imr_interface.s_addr = base_s_in->sin_addr.s_addr; 00375 00376 if (setsockopt(_xdvshow_shm.soc, IPPROTO_IP, IP_ADD_MEMBERSHIP, 00377 (char *)&mreq, sizeof(mreq)) < 0) { 00378 perror("ip_add_membership"); 00379 printf("multi addr : %s\n", inet_ntoa(mreq.imr_multiaddr)); 00380 printf("interface addr : %s\n", inet_ntoa(mreq.imr_interface)); 00381 } 00382 break; 00383 00384 #ifdef ENABLE_INET6 00385 case AF_INET6: 00386 memcpy((char *)&mreq6.ipv6mr_multiaddr, 00387 (char *)&s6_in->sin6_addr, 00388 sizeof(s6_in->sin6_addr)); 00389 00390 if (rtp_param->multi_ifname == NULL) { 00391 printf("ERROR : multicast interface required\n"); 00392 printf(" ex) xdvshow -j ff02::ab:cd -M fxp0\n"); 00393 return(-1); 00394 } 00395 mreq6.ipv6mr_interface = if_nametoindex(rtp_param->multi_ifname); 00396 00397 #ifdef IPV6_ADD_MEMBERSHIP 00398 if (setsockopt(_xdvshow_shm.soc, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, 00399 (char *)&mreq6, sizeof(mreq6)) < 0) { 00400 #else /* IPV6_ADD_MEMBERSHIP */ 00401 if (setsockopt(_xdvshow_shm.soc, IPPROTO_IPV6, IPV6_JOIN_GROUP, 00402 (char *)&mreq6, sizeof(mreq6)) < 0) { 00403 #endif /* IPV6_ADD_MEMBERSHIP */ 00404 perror("ip_add_membership"); 00405 } 00406 break; 00407 #endif /* ENABLE_INET6 */ 00408 00409 default: 00410 return(-1); 00411 break; 00412 } 00413 00414 return(1); 00415 }

int _multicast_str2addr struct xdvshow_rtp_param rtp_param  )  [static]
 

converts the multicast address into binary data in network byte order.

Parameters:
*rtp_param (struct xdvshow_rtp_param)
Returns:
1 on success. -1 if the address is invalid.

Definition at line 230 of file xdvshow-rtp.c.

References xdvshow_rtp_param::multi_addr_str, xdvshow_rtp_param::multi_s_addr, and rtp_param.

Referenced by _xdvshow_prepare_multicast().

00231 { 00232 #ifdef ENABLE_INET6 00233 struct addrinfo hints, *res; 00234 00235 memset(&hints, 0, sizeof(hints)); 00236 00237 hints.ai_socktype = SOCK_DGRAM; 00238 hints.ai_protocol = IPPROTO_UDP; 00239 00240 if (getaddrinfo(rtp_param->multi_addr_str, NULL, &hints, &res) != 0) { 00241 perror("getaddrinfo"); 00242 return(-1); 00243 } 00244 00245 memcpy(&rtp_param->multi_s_addr, res->ai_addr, res->ai_addrlen); 00246 #else /* ENABLE_INET6 */ 00247 struct sockaddr_in *s_in = (struct sockaddr_in *)&rtp_param->multi_s_addr; 00248 00249 s_in->sin_addr.s_addr = inet_addr(rtp_param->multi_addr_str); 00250 if (s_in->sin_addr.s_addr == -1) { 00251 return(-1); 00252 } 00253 #endif /* ENABLE_INET6 */ 00254 00255 return(1); 00256 }

int _xdvshow_prepare_multicast struct xdvshow_rtp_param rtp_param  )  [static]
 

converts the given address, checks if the address is correct and then joins the multicast group.

Parameters:
*rtp_param (struct xdvshow_rtp_param)
Returns:
1 on success. -1 otherwise.

Definition at line 425 of file xdvshow-rtp.c.

References _chk_multicast_addr(), _chk_multicast_family(), _multicast_join(), _multicast_str2addr(), and rtp_param.

Referenced by xdvshow_prepare_rtp().

00426 { 00427 int ret; 00428 00429 ret = _multicast_str2addr(rtp_param); 00430 if (ret < 0) { 00431 return(-1); 00432 } 00433 00434 ret = _chk_multicast_addr(rtp_param); 00435 if (ret < 0) { 00436 return(-1); 00437 } 00438 00439 ret = _chk_multicast_family(rtp_param); 00440 if (ret < 0) { 00441 return(-1); 00442 } 00443 00444 ret = _multicast_join(rtp_param); 00445 if (ret < 0) { 00446 return(-1); 00447 } 00448 00449 return(1); 00450 }

Here is the call graph for this function:

int _xdvshow_prepare_socket struct xdvshow_rtp_param rtp_param  )  [static]
 

creates a communication socket and returns a descriptor.

Returns:
1 on success. -1 if the function fails for some reason.

Definition at line 150 of file xdvshow-rtp.c.

References _xdvshow_shm, DPRINT, xdvshow_rtp_param::port, rtp_param, xdvshow_rtp_param::s_addr, and __xdvshow_shm::soc.

Referenced by xdvshow_prepare_rtp().

00151 { 00152 int soc; 00153 00154 struct sockaddr_in *s_in = (struct sockaddr_in *)&rtp_param->s_addr; 00155 #ifdef ENABLE_INET6 00156 struct sockaddr_in6 *s_in6 = (struct sockaddr_in6 *)&rtp_param->s_addr; 00157 #endif /* ENABLE_INET6 */ 00158 00159 #ifdef ENABLE_INET6 00160 if (rtp_param->s_addr.ss_family == AF_INET) { 00161 #ifndef NO_SS_LEN 00162 s_in->sin_len = sizeof(struct sockaddr_in); 00163 #endif /* NO_SS_LEN */ 00164 s_in->sin_port = htons(rtp_param->port); 00165 s_in->sin_addr.s_addr = htonl(INADDR_ANY); 00166 } else if (rtp_param->s_addr.ss_family == AF_INET6) { 00167 #ifndef NO_SS_LEN 00168 s_in6->sin6_len = sizeof(struct sockaddr_in6); 00169 #endif /* NO_SS_LEN */ 00170 s_in6->sin6_port = htons(rtp_param->port); 00171 } else { 00172 printf("Unknown family : %d\n", rtp_param->s_addr.ss_family); 00173 return(-1); 00174 } 00175 #else /* ENABLE_INET6 */ 00176 #ifndef NO_SS_LEN 00177 s_in->sin_len = sizeof(struct sockaddr_in); 00178 #endif /* NO_SS_LEN */ 00179 s_in->sin_port = htons(rtp_param->port); 00180 s_in->sin_addr.s_addr = htonl(INADDR_ANY); 00181 #endif /* ENABLE INET6 */ 00182 00183 #ifdef DEBUG 00184 if(rtp_param->s_addr.ss_family == PF_INET6) { 00185 DPRINT("Preparing IPv6 socket.\n"); 00186 } 00187 else if (rtp_param->s_addr.ss_family == PF_INET) { 00188 DPRINT("Preparing IPv4 socket.\n"); 00189 } 00190 else { 00191 DPRINT("Preparing niether IPv4 nor IPv6 socket.\n"); 00192 assert(0); 00193 } 00194 #else /* DEBUG */ 00195 printf("Using %s socket.\n", rtp_param->s_addr.ss_family == PF_INET6 ? "IPv6" : "IPv4" ); 00196 #endif /* DEBUG */ 00197 soc = socket(rtp_param->s_addr.ss_family, SOCK_DGRAM, 0); 00198 if (soc < 0) { 00199 perror("socket"); 00200 return(-1); 00201 } 00202 00203 #ifdef DEBUG 00204 DPRINT("Binding socket.\n"); 00205 #endif /* DEBUG */ 00206 #ifndef NO_SS_LEN 00207 if (bind(soc, (struct sockaddr *)&rtp_param->s_addr, rtp_param->s_addr.ss_len) < 0) { 00208 #else /* NO_SS_LEN */ 00209 if (bind(soc, (struct sockaddr *)&rtp_param->s_addr, sizeof(rtp_param->s_addr)) < 0) { 00210 #endif /* NO_SS_LEN */ 00211 perror("bind"); 00212 return(-1); 00213 } 00214 00215 _xdvshow_shm.soc = soc; 00216 #ifdef DEBUG 00217 DPRINT("Using socket fd=%d.\n", _xdvshow_shm.soc); 00218 #endif /* DEBUG */ 00219 00220 return(1); 00221 }

int _xdvshow_recv_dvrtp  )  [static]
 

internal function that acquires the DV stream from a network.

Returns:
0 on success, -1 on failure

Definition at line 457 of file xdvshow-rtp.c.

References _xdvshow_shm, audio_empty, audio_ready, __xdvshow_shm::audio_shm_frame, shm_frame_buf::data, DPRINT, DPRINT_BARE, DSEQ_MAX_NTSC, DSEQ_MAX_PAL, dv_format_type, DVFRAME_DATA_READY, DVFRAME_MAX_SIZE, flags_format_normal, flags_format_wide, flags_use_audio, shm_frame::frame_buf, shm_frame_buf::lock, MAX_PKT_LEN, shm_frame::next, SCT_AUDIO, SCT_HEADER, SCT_SUBCODE, SCT_VAUX, SCT_VIDEO, __xdvshow_shm::shm_frame, __xdvshow_shm::soc, ts_sem_wait, video_empty, and video_ready.

Referenced by xdvshow_prepare_rtp().

00458 { 00459 int n; 00460 int i; 00461 00462 u_long *recvbuf; 00463 u_long *recvbuf_ptr; 00464 00465 u_char *dvdata; 00466 u_char *audio_dvdata; 00467 00468 #ifdef DEBUG 00469 int sem_value = 0; 00470 int frame_length = 0; 00471 int iDebugSemVal; 00472 #endif /* DEBUG */ 00473 00474 unsigned int dbn, dseq, seq, sct; 00475 00476 unsigned int dseq_max; 00477 unsigned int dseq_stream_max = 0; 00478 unsigned int dseq_stream_max_count = 0; 00479 00480 recvbuf = (u_long *) malloc(sizeof(u_long) * MAX_PKT_LEN); 00481 00482 /* XXX - tady je docela neprehledna interakce se zjistovanim typu videa 00483 * v xdvshow-main.c!! Jak to vychazi s casovanim? */ 00484 /* XXX - nemela by se kontrola formatu delat pozdeji a casteji?? Ted se zda, 00485 ze to vdycky skonci na dseq_max = 11! */ 00486 switch (dv_format_type) { 00487 case e_dv_system_525_60: 00488 dseq_max = DSEQ_MAX_NTSC; 00489 break; 00490 00491 case e_dv_system_625_50: 00492 dseq_max = DSEQ_MAX_PAL; 00493 break; 00494 00495 default: 00496 free(recvbuf); 00497 return(-1); 00498 } 00499 00500 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00501 audio_dvdata = _xdvshow_shm.audio_shm_frame->frame_buf->data; 00502 00503 while (1) { 00504 00505 DPRINT("Receiving RTP.\n"); 00506 00507 n = read(_xdvshow_shm.soc, (char *)recvbuf, sizeof(u_long) * MAX_PKT_LEN); 00508 00509 if (n < 1) { 00510 return(-1); 00511 } 00512 00513 00514 #ifdef DEBUG 00515 received += n; 00516 frame_length +=n; 00517 packets++; 00518 DPRINT("RECEIVED %ldb; Received packets: %ld\n", received, packets); 00519 #endif /* DEBUG */ 00520 00521 /* XXX - recvbuf -> u_char */ 00522 assert(sizeof(rtp_hdr_t) % 4 == 0); 00523 for (i=0; i<(n - sizeof(rtp_hdr_t))/80; i++) { 00524 DPRINT_BARE("."); 00525 recvbuf_ptr = recvbuf + (sizeof(rtp_hdr_t)+80*i)/4; 00526 assert((char *)recvbuf_ptr < (char *)recvbuf + n); 00527 dbn = (ntohl(*recvbuf_ptr) >> 8) & 0xff; 00528 dseq = (ntohl(*recvbuf_ptr) >> 20) & 0xf; 00529 seq = (ntohl(*recvbuf_ptr) >> 24) & 0xf; 00530 sct = (ntohl(*recvbuf_ptr) >> 29) & 0x7; 00531 00532 if (sct > 4) { 00533 DPRINT_BARE("\n"); 00534 DPRINT("Data error: SCT > 4! sct = %d\n", sct); 00535 continue; 00536 } 00537 00538 /* Hard-testing just DSEQ_MAX_PAL is to facilitate on-the-fly change from 00539 * NTSC to PAL without restarting application. 00540 */ 00541 if (dseq > dseq_max) { 00542 DPRINT_BARE("\n"); 00543 DPRINT("Data error: DSEQ > DSEQ_MAX! dseq = %d, dseq_max = %d\n", dseq, dseq_max); 00544 } 00545 if (dseq > DSEQ_MAX_PAL) { 00546 DPRINT_BARE("\n"); 00547 DPRINT("Data error: DSEQ > DSEQ_MAX_PAL! dseq = %d, DSEQ_MAX_PAL = %d\n", dseq, DSEQ_MAX_PAL); 00548 continue; 00549 } 00550 00551 /* XXX This is dirty temporary solution for switching PAL/NTSC 00552 on the fly. It measures dseq maximum in window of 255 and uses it as 00553 dseq_max. 00554 */ 00555 if (dseq_stream_max_count >= 255) { 00556 if (dseq_stream_max != dseq_max && (dseq_stream_max == DSEQ_MAX_PAL || dseq_stream_max == DSEQ_MAX_NTSC) ) { 00557 dseq_max = dseq_stream_max; 00558 } 00559 dseq_stream_max_count = 0; 00560 dseq_stream_max = 0; 00561 } 00562 else { 00563 if (dseq_stream_max < dseq) { 00564 dseq_stream_max = dseq; 00565 } 00566 ++dseq_stream_max_count; 00567 } 00568 00569 switch (sct) { 00570 00571 case SCT_HEADER: 00572 if((dseq * 150 *80) <= (DVFRAME_MAX_SIZE - 80)) 00573 memcpy(&dvdata[dseq * 150 * 80], recvbuf_ptr, 80); 00574 else { 00575 DPRINT_BARE("\n"); 00576 DPRINT("memcpy dropped - dvdata size %d exceeded by %d\ndseq = %d\n", DVFRAME_MAX_SIZE, ((dseq * 150 * 80) - DVFRAME_MAX_SIZE + 80), dbn); 00577 } 00578 break; 00579 00580 case SCT_SUBCODE: 00581 if(dbn > 1) { 00582 DPRINT_BARE("\n"); 00583 DPRINT("Data error: DBN > 1\ndbn = %d\n", dbn); 00584 break; 00585 } 00586 if((dseq * 150 + 1 + dbn) *80 <= (DVFRAME_MAX_SIZE - 80)) 00587 memcpy(&dvdata[(dseq * 150 + 1 + dbn) * 80], recvbuf_ptr, 80); 00588 else { 00589 DPRINT_BARE("\n"); 00590 DPRINT("memcpy dropped - dvdata size %d exceeded by %d\ndseq = %d\n", DVFRAME_MAX_SIZE, ((dseq * 150 + 1 + dbn)* 80 - DVFRAME_MAX_SIZE + 80), dbn); 00591 } 00592 break; 00593 00594 00595 case SCT_VAUX: 00596 if(dbn > 2) { 00597 DPRINT_BARE("\n"); 00598 DPRINT("Data error: DBN > 2\ndbn = %d\n", dbn); 00599 break; 00600 } 00601 if((dseq * 150 + dbn + 3)*80 <= (DVFRAME_MAX_SIZE - 80)) 00602 memcpy(&dvdata[(dseq * 150 + dbn + 3) * 80], recvbuf_ptr, 80); 00603 else { 00604 DPRINT_BARE("\n"); 00605 DPRINT("memcpy dropped - dvdata size %d exceeded by %d\ndseq = %d, dbn = %d\n", DVFRAME_MAX_SIZE, ((dseq * 150 + 6 + dbn * 16)*80 - DVFRAME_MAX_SIZE + 80), dseq, dbn); 00606 } 00607 break; 00608 00609 case SCT_AUDIO: 00610 if(dbn > 8) { 00611 DPRINT_BARE("\n"); 00612 DPRINT("Data error: DBN > 8\ndbn = %d\n", dbn); 00613 break; 00614 } 00615 DPRINT_BARE("*"); 00616 if((dseq * 150 + 6 + dbn * 16)*80 <= (DVFRAME_MAX_SIZE - 80)) 00617 memcpy(&dvdata[(dseq * 150 + 6 + dbn*16) * 80], recvbuf_ptr, 80); 00618 else { 00619 DPRINT_BARE("\n"); 00620 DPRINT("memcpy dropped - dvdata size %d exceeded by %d\ndseq = %d, dbn = %d\n", DVFRAME_MAX_SIZE, ((dseq * 150 + 6 + dbn * 16)*80 - DVFRAME_MAX_SIZE + 80), dseq, dbn); 00621 break; 00622 } 00623 if (flags_use_audio) { 00624 DPRINT_BARE("(*)"); 00625 if((dseq * 150 + 6 + dbn * 16) * 80 <= (DVFRAME_MAX_SIZE - 80)) 00626 memcpy(&audio_dvdata[(dseq * 150 + 6 + dbn * 16) * 80], recvbuf_ptr, 80); 00627 else { 00628 DPRINT_BARE("\n"); 00629 DPRINT("memcpy dropped - dvdata size %d exceeded by %d\ndseq = %d, dbn = %d\n", DVFRAME_MAX_SIZE, ((dseq * 150 + 6 + dbn * 16)*80 - DVFRAME_MAX_SIZE + 80), dseq, dbn); 00630 break; 00631 } 00632 00633 /* XXX This is very nasty and prevents from going from PAL to NTSC 00634 unless dseq_max is adjusted properly since dseq_max for PAL is never 00635 reached in NTSC. 00636 */ 00637 if (dseq == dseq_max && dbn == 8) { 00638 #ifdef DEBUG 00639 if(sem_getvalue(&audio_ready, &iDebugSemVal)) { 00640 perror("Unable to get value of audio_ready semaphore!"); 00641 exit(EXIT_FAILURE); 00642 } 00643 DPRINT("semaphore audio_ready value: %d\n", iDebugSemVal); 00644 00645 if(sem_getvalue(&audio_empty, &iDebugSemVal)) { 00646 perror("Unable to get value of audio_empty semaphore!"); 00647 exit(EXIT_FAILURE); 00648 } 00649 DPRINT("semaphore audio_empty value: %d\n", iDebugSemVal); 00650 #endif /* DEBUG */ 00651 00652 /* The sem_post and sem_wait should happen if 16:9/4:3 detection is 00653 * finished. This was the problem with xdvshow deadlocking after error 00654 * in detection of 16:9/4:3 formats on FreeBSD. At least I hope so. */ 00655 if ( !( ((flags_format_normal == 0) && (flags_format_wide == 0)) 00656 || ((flags_format_normal != 0) && (flags_format_wide != 0)) ) ) 00657 { 00658 sem_post(&audio_ready); 00659 ts_sem_wait(&audio_empty); 00660 } 00661 00662 _xdvshow_shm.audio_shm_frame = _xdvshow_shm.audio_shm_frame->next; 00663 audio_dvdata = _xdvshow_shm.audio_shm_frame->frame_buf->data; 00664 } 00665 } 00666 00667 break; 00668 00669 case SCT_VIDEO: 00670 /* XXX - 2 veci: 00671 1) kontrola dbn % 15 == 0 00672 tohle z nejakeho duvodu neni potreba a fakt je to asi 00673 celociselny deleni; dbn % 15 != 0 temer furt a kdyz se to 00674 vyeliminuje, tak se nic nezobrazi 00675 2) kontrola preteceni pameti 00676 */ 00677 if(dbn > 134) { 00678 DPRINT_BARE("\n"); 00679 DPRINT("Data error: DBN > 134\ndbn = %d\n", dbn); 00680 break; 00681 } 00682 if((dseq * 150 + 7 + dbn + dbn/15) * 80 > (DVFRAME_MAX_SIZE - 80)) { 00683 DPRINT_BARE("\n"); 00684 DPRINT("memcpy dropped - dvdata size %d exceeded by %d\ndseq = %d, dbn = %d\n", DVFRAME_MAX_SIZE, ((dseq * 150 + 6 +7 + dbn + dbn/15)*80 - DVFRAME_MAX_SIZE + 80), dseq, dbn); 00685 } 00686 memcpy(&dvdata[(dseq * 150 + 7 + dbn + dbn/15) * 80], 00687 recvbuf_ptr, 00688 80); 00689 00690 if (dseq == dseq_max && dbn == 134) { 00691 _xdvshow_shm.shm_frame->frame_buf->lock = DVFRAME_DATA_READY; 00692 00693 #ifdef DEBUG 00694 DPRINT("RECEIVED frame no. %d\n", sem_value++); 00695 DPRINT("RECEIVED frame length: %d\n", frame_length); 00696 00697 if(sem_getvalue(&video_ready, &iDebugSemVal)) { 00698 perror("Unable to get value of video_ready semaphore!"); 00699 exit(EXIT_FAILURE); 00700 } 00701 DPRINT("semaphore video_ready value: %d\n", iDebugSemVal); 00702 00703 if(sem_getvalue(&video_empty, &iDebugSemVal)) { 00704 perror("Unable to get value of video_empty semaphore!"); 00705 exit(EXIT_FAILURE); 00706 } 00707 DPRINT("semaphore video_empty value: %d\n", iDebugSemVal); 00708 00709 frame_length = 0; 00710 #endif /* DEBUG */ 00711 00712 sem_post(&video_ready); 00713 ts_sem_wait(&video_empty); 00714 00715 _xdvshow_shm.shm_frame = _xdvshow_shm.shm_frame->next; 00716 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00717 } 00718 break; 00719 00720 default: 00721 break; 00722 } 00723 } 00724 } 00725 00726 return(0); 00727 }

void* xdvshow_ping_reflector void *  data  ) 
 

periodically sends a dummy packet to the packet reflector.

The dummy packet is sent to rtp_param.port + 1.

Parameters:
*data is actually hostname (char *) with the packet reflector's hostname.
Returns:
void.

Definition at line 50 of file xdvshow-rtp.c.

References xdvshow_rtp_param::port, REFLECTOR_PING_INTERVAL, and rtp_param.

Referenced by main().

00051 { 00052 struct hostent *host = NULL; 00053 char *hostname = data; 00054 struct sockaddr_in reflector_addr; 00055 00056 int sock; 00057 00058 /* Code lama :-) */ 00059 00060 printf("Trying reflector: %s/%d\n", hostname, rtp_param.port); 00061 00062 if (!(host = gethostbyname(hostname))) { 00063 herror(hostname); 00064 return((void *)1); 00065 } 00066 00067 reflector_addr.sin_family = (sa_family_t) AF_INET; 00068 reflector_addr.sin_addr.s_addr = INADDR_ANY; 00069 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 00070 perror("socket()"); 00071 free(host->h_name); 00072 free(host->h_aliases); 00073 free(host->h_addr_list); 00074 free(host); 00075 return((void *)2); 00076 } 00077 reflector_addr.sin_port = htons(rtp_param.port + 1); 00078 if (bind(sock, (struct sockaddr *) &reflector_addr, sizeof(reflector_addr))) { 00079 perror("bind()"); 00080 free(host->h_name); 00081 free(host->h_aliases); 00082 free(host->h_addr_list); 00083 free(host); 00084 return((void *)3); 00085 } 00086 00087 reflector_addr.sin_addr = **(struct in_addr **) host->h_addr_list; 00088 00089 printf("Using reflector: %s/%d\n", hostname, rtp_param.port); 00090 00091 while (1) { 00092 if(sendto(sock, "", 1, 0, (struct sockaddr *) &reflector_addr, sizeof(reflector_addr)) == -1) { 00093 perror("reflector ping sendto"); 00094 assert(0); 00095 } 00096 sleep(REFLECTOR_PING_INTERVAL); 00097 } 00098 }

void* xdvshow_prepare_rtp void *  data  ) 
 

Public function that handles the input from a network.

Returns:
This function is never supposed to come back. -1 if the function fails for some reason.

Definition at line 106 of file xdvshow-rtp.c.

References _xdvshow_alloc_shm(), _xdvshow_attach_shm(), _xdvshow_prepare_multicast(), _xdvshow_prepare_socket(), _xdvshow_recv_dvrtp(), _xdvshow_shm, DPRINT, and __xdvshow_shm::parent_pid.

Referenced by main().

00107 { 00108 int ret; 00109 00110 struct xdvshow_rtp_param *p_rtp_param = data; 00111 00112 if (p_rtp_param == NULL) { 00113 return((void *)-1); 00114 } 00115 00116 ret = _xdvshow_alloc_shm(); 00117 if (ret < 0) { 00118 return((void *)-1); 00119 } 00120 00121 ret = _xdvshow_prepare_socket(p_rtp_param); 00122 00123 if (p_rtp_param->multi_addr_str != NULL) { 00124 ret = _xdvshow_prepare_multicast(p_rtp_param); 00125 if (ret < 0) { 00126 kill(_xdvshow_shm.parent_pid, SIGINT); 00127 exit(EXIT_FAILURE); 00128 } 00129 } 00130 00131 ret = _xdvshow_attach_shm(); 00132 assert(ret == 1); 00133 00134 DPRINT("Calling xdvshow_recv_dvrtp.\n"); 00135 /* THIS IS NOT SUPPOSED TO COME BACK */ 00136 if(_xdvshow_recv_dvrtp()) { 00137 DPRINT("The _xdvshow_recv_dvrtp is supposed to never return.\n"); 00138 exit(EXIT_FAILURE); 00139 } 00140 00141 exit(EXIT_SUCCESS); /* XXX */ 00142 }

Here is the call graph for this function:


Generated on Wed Nov 3 19:19:02 2004 for xdvshow by doxygen 1.3.7