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

xdvshow-rtp.c

Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H 00002 #include <config.h> 00003 #endif /* HAVE_CONFIG_H */ 00004 00005 #include <string.h> 00006 #include <sys/socket.h> 00007 #include <netinet/in.h> 00008 #include <netdb.h> 00009 #ifndef S_SPLINT_S 00010 #include <net/if.h> 00011 #endif 00012 #include <arpa/inet.h> 00013 #include <stdio.h> 00014 #include <unistd.h> 00015 #include <errno.h> 00016 #include <signal.h> 00017 #include <pthread.h> 00018 #include <assert.h> 00019 00020 #include <libdv/dv_types.h> 00021 #include <semaphore.h> 00022 00023 #include "RTP.h" 00024 00025 #include "xdvshow-const.h" 00026 00027 #include "xdvshow-shm.h" 00028 #include "xdvshow-flags.h" 00029 #include "xdvshow-rtp.h" 00030 #include "xdvshow-defs.h" 00031 00032 static int _xdvshow_prepare_socket __P((struct xdvshow_rtp_param *)); 00033 static int _xdvshow_prepare_multicast __P((struct xdvshow_rtp_param *)); 00034 static int _xdvshow_recv_dvrtp __P((void)); 00035 00036 #ifdef DEBUG 00037 unsigned long int received = 0; 00038 unsigned long int packets = 0; 00039 #endif /* DEBUG */ 00040 00049 void * 00050 xdvshow_ping_reflector(void *data) 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 } 00099 00105 void * 00106 xdvshow_prepare_rtp(void *data) 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 } 00143 00149 static int 00150 _xdvshow_prepare_socket(struct xdvshow_rtp_param *rtp_param) 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 } 00222 00229 static int 00230 _multicast_str2addr(struct xdvshow_rtp_param *rtp_param) 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 } 00257 00264 static int 00265 _chk_multicast_addr(struct xdvshow_rtp_param *rtp_param) 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 } 00300 00301 00308 static int 00309 _chk_multicast_family(struct xdvshow_rtp_param *rtp_param) 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 } 00349 00356 static int 00357 _multicast_join(struct xdvshow_rtp_param *rtp_param) 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 } 00416 00424 static int 00425 _xdvshow_prepare_multicast(struct xdvshow_rtp_param *rtp_param) 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 } 00451 00456 static int 00457 _xdvshow_recv_dvrtp() 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 } 00728

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