Changeset 6005 for pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
- Timestamp:
- May 26, 2019 1:18:02 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
r5907 r6005 19 19 */ 20 20 #include <pjmedia/transport_udp.h> 21 #include <pj/compat/socket.h> 21 22 #include <pj/addr_resolv.h> 22 23 #include <pj/assert.h> … … 27 28 #include <pj/rand.h> 28 29 #include <pj/string.h> 29 30 30 31 31 /* Maximum size of incoming RTP packet */ … … 155 155 unsigned pct_lost); 156 156 static pj_status_t transport_destroy (pjmedia_transport *tp); 157 158 #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \159 PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0160 157 static pj_status_t transport_restart (pj_bool_t is_rtp, 161 158 struct transport_udp *udp); 162 #endif163 159 164 160 static pjmedia_transport_op transport_udp_op = … … 454 450 } 455 451 452 /* Call RTP cb. */ 453 static void call_rtp_cb(struct transport_udp *udp, pj_ssize_t bytes_read, 454 pj_bool_t *rem_switch) 455 { 456 void (*cb)(void*,void*,pj_ssize_t); 457 void (*cb2)(pjmedia_tp_cb_param*); 458 void *user_data; 459 460 cb = udp->rtp_cb; 461 cb2 = udp->rtp_cb2; 462 user_data = udp->user_data; 463 464 if (cb2) { 465 pjmedia_tp_cb_param param; 466 467 param.user_data = user_data; 468 param.pkt = udp->rtp_pkt; 469 param.size = bytes_read; 470 param.src_addr = &udp->rtp_src_addr; 471 param.rem_switch = PJ_FALSE; 472 (*cb2)(¶m); 473 if (rem_switch) 474 *rem_switch = param.rem_switch; 475 } else if (cb) { 476 (*cb)(user_data, udp->rtp_pkt, bytes_read); 477 } 478 } 479 480 /* Call RTCP cb. */ 481 static void call_rtcp_cb(struct transport_udp *udp, pj_ssize_t bytes_read) 482 { 483 void(*cb)(void*, void*, pj_ssize_t); 484 void *user_data; 485 486 cb = udp->rtcp_cb; 487 user_data = udp->user_data; 488 489 if (cb) 490 (*cb)(user_data, udp->rtcp_pkt, bytes_read); 491 } 456 492 457 493 /* Notification from ioqueue about incoming RTP packet */ … … 463 499 pj_status_t status; 464 500 pj_bool_t rem_switch = PJ_FALSE; 501 pj_bool_t transport_restarted = PJ_FALSE; 502 unsigned num_err = 0; 503 pj_status_t last_err = PJ_SUCCESS; 465 504 466 505 PJ_UNUSED_ARG(op_key); … … 470 509 udp = (struct transport_udp*) pj_ioqueue_get_user_data(key); 471 510 472 #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \473 PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0474 511 if (-bytes_read == PJ_ESOCKETSTOP) { 475 512 /* Try to recover by restarting the transport. */ 476 PJ_LOG(4, (udp->base.name, "Restarting RTP transport"));477 513 status = transport_restart(PJ_TRUE, udp); 478 if (status == PJ_SUCCESS) { 479 PJ_LOG(4, (udp->base.name, "Success restarting RTP transport")); 480 } else { 481 PJ_PERROR(1, (udp->base.name, status, 482 "Error restarting RTP transport")); 514 if (status != PJ_SUCCESS) { 515 bytes_read = -PJ_ESOCKETSTOP; 516 call_rtp_cb(udp, bytes_read, NULL); 483 517 } 484 518 return; 485 519 } 486 #endif487 520 488 521 do { 489 void (*cb)(void*,void*,pj_ssize_t);490 void (*cb2)(pjmedia_tp_cb_param*);491 void *user_data;492 522 pj_bool_t discard = PJ_FALSE; 493 494 cb = udp->rtp_cb;495 cb2 = udp->rtp_cb2;496 user_data = udp->user_data;497 523 498 524 /* Simulate packet lost on RX direction */ … … 507 533 508 534 //if (!discard && udp->attached && cb) 509 if (!discard) { 510 if (cb2) { 511 pjmedia_tp_cb_param param; 512 513 param.user_data = user_data; 514 param.pkt = udp->rtp_pkt; 515 param.size = bytes_read; 516 param.src_addr = &udp->rtp_src_addr; 517 param.rem_switch = PJ_FALSE; 518 (*cb2)(¶m); 519 rem_switch = param.rem_switch; 520 } else if (cb) { 521 (*cb)(user_data, udp->rtp_pkt, bytes_read); 522 } 535 if (!discard && 536 (-bytes_read != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL))) 537 { 538 call_rtp_cb(udp, bytes_read, &rem_switch); 523 539 } 524 540 … … 566 582 udp->rtp_addrlen = sizeof(udp->rtp_src_addr); 567 583 status = pj_ioqueue_recvfrom(udp->rtp_key, &udp->rtp_read_op, 568 udp->rtp_pkt, &bytes_read, 0, 569 &udp->rtp_src_addr, 570 &udp->rtp_addrlen); 571 572 if (status != PJ_EPENDING && status != PJ_SUCCESS) 584 udp->rtp_pkt, &bytes_read, 0, 585 &udp->rtp_src_addr, 586 &udp->rtp_addrlen); 587 588 if (status != PJ_EPENDING && status != PJ_SUCCESS) { 589 if (transport_restarted && last_err == status) { 590 /* Still the same error after restart */ 591 bytes_read = -PJ_ESOCKETSTOP; 592 call_rtp_cb(udp, bytes_read, NULL); 593 break; 594 } else if (PJMEDIA_IGNORE_RECV_ERR_CNT) { 595 if (last_err == status) { 596 ++num_err; 597 } else { 598 num_err = 1; 599 last_err = status; 600 } 601 602 if (status == PJ_ESOCKETSTOP || 603 num_err > PJMEDIA_IGNORE_RECV_ERR_CNT) 604 { 605 status = transport_restart(PJ_TRUE, udp); 606 if (status != PJ_SUCCESS) { 607 bytes_read = -PJ_ESOCKETSTOP; 608 call_rtp_cb(udp, bytes_read, NULL); 609 break; 610 } 611 transport_restarted = PJ_TRUE; 612 num_err = 0; 613 } 614 } 573 615 bytes_read = -status; 574 616 } 575 617 } while (status != PJ_EPENDING && status != PJ_ECANCELLED && 576 618 udp->started); … … 585 627 struct transport_udp *udp; 586 628 pj_status_t status = PJ_SUCCESS; 629 pj_bool_t transport_restarted = PJ_FALSE; 630 unsigned num_err = 0; 631 pj_status_t last_err = PJ_SUCCESS; 587 632 588 633 PJ_UNUSED_ARG(op_key); … … 592 637 udp = (struct transport_udp*) pj_ioqueue_get_user_data(key); 593 638 594 #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \595 PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0596 639 if (-bytes_read == PJ_ESOCKETSTOP) { 597 640 /* Try to recover by restarting the transport. */ 598 PJ_LOG(4, (udp->base.name, "Restarting RTCP transport"));599 641 status = transport_restart(PJ_FALSE, udp); 600 if (status == PJ_SUCCESS) { 601 PJ_LOG(4, (udp->base.name, "Success restarting RTCP transport")); 602 } else { 603 PJ_PERROR(1, (udp->base.name, status, 604 "Error restarting RTCP transport")); 642 if (status != PJ_SUCCESS) { 643 bytes_read = -PJ_ESOCKETSTOP; 644 call_rtcp_cb(udp, bytes_read); 605 645 } 606 646 return; 607 647 } 608 #endif609 648 610 649 do { 611 void (*cb)(void*,void*,pj_ssize_t); 612 void *user_data; 613 614 cb = udp->rtcp_cb; 615 user_data = udp->user_data; 616 617 //if (udp->attached && cb) 618 if (cb) 619 (*cb)(user_data, udp->rtcp_pkt, bytes_read); 650 call_rtcp_cb(udp, bytes_read); 620 651 621 652 #if defined(PJMEDIA_TRANSPORT_SWITCH_REMOTE_ADDR) && \ … … 656 687 &udp->rtcp_src_addr, 657 688 &udp->rtcp_addr_len); 658 if (status != PJ_EPENDING && status != PJ_SUCCESS) 689 690 if (status != PJ_EPENDING && status != PJ_SUCCESS) { 691 if (transport_restarted && last_err == status) { 692 /* Still the same error after restart */ 693 bytes_read = -PJ_ESOCKETSTOP; 694 call_rtcp_cb(udp, bytes_read); 695 break; 696 } else if (PJMEDIA_IGNORE_RECV_ERR_CNT) { 697 if (last_err == status) { 698 ++num_err; 699 } else { 700 num_err = 1; 701 last_err = status; 702 } 703 704 if (status == PJ_ESOCKETSTOP || 705 num_err > PJMEDIA_IGNORE_RECV_ERR_CNT) 706 { 707 status = transport_restart(PJ_FALSE, udp); 708 if (status != PJ_SUCCESS) { 709 bytes_read = -PJ_ESOCKETSTOP; 710 call_rtcp_cb(udp, bytes_read); 711 break; 712 } 713 transport_restarted = PJ_TRUE; 714 num_err = 0; 715 } 716 } 659 717 bytes_read = -status; 660 718 } 661 719 } while (status != PJ_EPENDING && status != PJ_ECANCELLED && 662 720 udp->started); … … 928 986 PJ_ASSERT_RETURN(size <= PJMEDIA_MAX_MTU, PJ_ETOOBIG); 929 987 988 if (!udp->started) { 989 return PJ_SUCCESS; 990 } 991 930 992 /* Simulate packet lost on TX direction */ 931 993 if (udp->tx_drop_pct) { … … 985 1047 986 1048 //PJ_ASSERT_RETURN(udp->attached, PJ_EINVALIDOP); 1049 1050 if (!udp->started) { 1051 return PJ_SUCCESS; 1052 } 987 1053 988 1054 if (addr == NULL) { … … 1181 1247 } 1182 1248 1183 #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \ 1184 PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0 1185 static pj_status_t transport_restart(pj_bool_t is_rtp, 1249 static pj_status_t transport_restart(pj_bool_t is_rtp, 1186 1250 struct transport_udp *udp) 1187 1251 { … … 1194 1258 pj_ssize_t size; 1195 1259 1260 PJ_LOG(4, (udp->base.name, "Restarting %s transport", 1261 (is_rtp)?"RTP":"RTCP")); 1262 1263 udp->started = PJ_FALSE; 1196 1264 /* Destroy existing socket, if any. */ 1197 1265 if (key) { … … 1208 1276 pj_sock_close(*sock); 1209 1277 } 1210 *sock = PJ_INVALID_SOCKET; 1278 *sock = PJ_INVALID_SOCKET; 1211 1279 1212 1280 /* Create socket */ … … 1224 1292 /* Set buffer size for RTP socket */ 1225 1293 #if PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE 1226 {1294 if (is_rtp) { 1227 1295 unsigned sobuf_size = PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE; 1228 1296 1229 status = pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_RCVBUF(), 1230 PJ_TRUE, &sobuf_size); 1231 if (status != PJ_SUCCESS) { 1232 pj_perror(3, udp->base.name, status, "Failed setting SO_RCVBUF"); 1233 } else { 1234 if (sobuf_size < PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE) { 1235 PJ_LOG(4, (udp->base.name, 1236 "Warning! Cannot set SO_RCVBUF as configured, " 1237 "now=%d, configured=%d", 1238 sobuf_size, PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE)); 1239 } else { 1240 PJ_LOG(5, (udp->base.name, "SO_RCVBUF set to %d", sobuf_size)); 1241 } 1242 } 1297 pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_RCVBUF(), 1298 PJ_TRUE, &sobuf_size); 1243 1299 } 1244 1300 #endif 1245 1301 #if PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE 1246 {1302 if (is_rtp) { 1247 1303 unsigned sobuf_size = PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE; 1248 1304 1249 status = pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_SNDBUF(), 1250 PJ_TRUE, &sobuf_size); 1251 if (status != PJ_SUCCESS) { 1252 pj_perror(3, udp->base.name, status, "Failed setting SO_SNDBUF"); 1253 } else { 1254 if (sobuf_size < PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE) { 1255 PJ_LOG(4, (udp->base.name, 1256 "Warning! Cannot set SO_SNDBUF as configured, " 1257 "now=%d, configured=%d", 1258 sobuf_size, PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE)); 1259 } else { 1260 PJ_LOG(5, (udp->base.name, "SO_SNDBUF set to %d", sobuf_size)); 1261 } 1262 } 1305 pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_SNDBUF(), 1306 PJ_TRUE, &sobuf_size); 1263 1307 } 1264 1308 #endif … … 1296 1340 goto on_error; 1297 1341 1298 1342 udp->started = PJ_TRUE; 1343 PJ_LOG(4, (udp->base.name, "Success restarting %s transport", 1344 (is_rtp)?"RTP":"RTCP")); 1299 1345 return PJ_SUCCESS; 1300 1346 on_error: … … 1303 1349 *sock = PJ_INVALID_SOCKET; 1304 1350 } 1351 PJ_PERROR(1, (udp->base.name, status, 1352 "Error restarting %s transport", (is_rtp)?"RTP":"RTCP")); 1305 1353 return status; 1306 1354 } 1307 #endif
Note: See TracChangeset
for help on using the changeset viewer.