Changeset 615


Ignore:
Timestamp:
Jul 18, 2006 9:12:24 PM (18 years ago)
Author:
bennylp
Message:

Undo modification to use timer, and back to using threads as the performance is not good

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/samples/siprtp.c

    r582 r615  
    123123    pjmedia_rtcp_session rtcp;              /* incoming RTCP session.   */ 
    124124 
    125     /* Timer to send RTP and RTCP: */ 
    126     pj_timer_entry       rtp_timer;         /* timer to send RTP pkt.   */ 
    127     pj_timer_entry       rtcp_timer;        /* timer to send RTCP pkt.  */ 
     125    /* Thread: */ 
     126    pj_bool_t            thread_quit_flag;  /* Stop media thread.       */ 
     127    pj_thread_t         *thread;            /* Media thread.            */ 
    128128}; 
    129129 
     
    223223static void on_rx_rtcp(void *user_data, const void *pkt, pj_ssize_t size); 
    224224 
    225 /* This callback is called when it's time to send RTP packet */ 
    226 static void on_tx_rtp( pj_timer_heap_t *timer_heap, 
    227                        struct pj_timer_entry *entry); 
    228  
    229 /* This callback is called when it's time to send RTCP packet. */ 
    230 static void on_tx_rtcp(pj_timer_heap_t *timer_heap, 
    231                        struct pj_timer_entry *entry); 
    232  
    233  
    234225/* Display error */ 
    235226static void app_perror(const char *sender, const char *title,  
     
    397388     * initialized. 
    398389     */ 
    399     status = pjmedia_endpt_create(&app.cp.factory,  
    400                                   pjsip_endpt_get_ioqueue(app.sip_endpt), 0,  
    401                                   &app.med_endpt); 
     390    status = pjmedia_endpt_create(&app.cp.factory, NULL, 1, &app.med_endpt); 
    402391    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
    403392 
     
    419408             * to current port number. 
    420409             */ 
    421             struct media_stream *m = &app.call[i].media[j]; 
    422410            int retry; 
    423411 
    424             m->call_index = i; 
    425             m->media_index = j; 
    426  
    427             m->rtp_timer.user_data = m; 
    428             m->rtp_timer.cb = &on_tx_rtp; 
    429  
    430             m->rtcp_timer.user_data = m; 
    431             m->rtcp_timer.cb = &on_tx_rtcp; 
    432  
     412            app.call[i].media[j].call_index = i; 
     413            app.call[i].media[j].media_index = j; 
    433414 
    434415            status = -1; 
     
    588569    } 
    589570 
     571    call = &app.call[i]; 
     572 
    590573    /* Verify that we can handle the request. */ 
    591574    options = 0; 
    592575    status = pjsip_inv_verify_request(rdata, &options, NULL, NULL, 
    593                                       app.sip_endpt, &tdata); 
     576                                   app.sip_endpt, &tdata); 
    594577    if (status != PJ_SUCCESS) { 
    595  
    596578        /* 
    597579         * No we can't handle the incoming INVITE request. 
    598580         */ 
    599  
    600581        if (tdata) { 
    601582            pjsip_response_addr res_addr; 
    602  
     583             
    603584            pjsip_get_response_addr(tdata->pool, rdata, &res_addr); 
    604             pjsip_endpt_send_response(app.sip_endpt, &res_addr, tdata,  
    605                                       NULL, NULL); 
    606  
     585            pjsip_endpt_send_response(app.sip_endpt, &res_addr, tdata, 
     586                NULL, NULL); 
     587             
    607588        } else { 
    608  
     589             
    609590            /* Respond with 500 (Internal Server Error) */ 
    610591            pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 500, NULL, 
    611                                           NULL, NULL); 
    612         } 
    613  
     592                NULL, NULL); 
     593        } 
     594         
    614595        return; 
    615     }  
    616  
    617     call = &app.call[i]; 
     596    } 
    618597 
    619598    /* Create UAS dialog */ 
     
    803782 
    804783 
    805 #if defined(PJ_WIN32) && PJ_WIN32 != 0 
    806 #include <windows.h> 
    807 static void boost_priority(void) 
    808 { 
    809     SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS); 
    810     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 
    811 } 
    812  
    813 #else 
    814 #  define boost_priority() 
    815 #endif 
    816  
    817  
    818784/* Worker thread for SIP */ 
    819785static int sip_worker_thread(void *arg) 
     
    821787    PJ_UNUSED_ARG(arg); 
    822788 
    823     boost_priority(); 
    824  
    825789    while (!app.thread_quit) { 
    826         pj_time_val timeout = {0, 1}; 
     790        pj_time_val timeout = {0, 10}; 
    827791        pjsip_endpt_handle_events(app.sip_endpt, &timeout); 
    828792    } 
     
    10831047 
    10841048 
     1049#if defined(PJ_WIN32) && PJ_WIN32 != 0 
     1050#include <windows.h> 
     1051static void boost_priority(void) 
     1052{ 
     1053    SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS); 
     1054    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 
     1055} 
     1056 
     1057#else 
     1058#  define boost_priority() 
     1059#endif 
     1060 
     1061 
    10851062/* 
    10861063 * This callback is called by media transport on receipt of RTP packet. 
     
    11261103} 
    11271104 
    1128 /* This callback is called when it's time to send RTP packet */ 
    1129 static void on_tx_rtp( pj_timer_heap_t *timer_heap, 
    1130                        struct pj_timer_entry *entry) 
    1131 { 
    1132     pj_status_t status; 
    1133     const pjmedia_rtp_hdr *hdr; 
    1134     pj_ssize_t size; 
    1135     int hdrlen; 
    1136     pj_time_val interval; 
    1137     char packet[512]; 
    1138     struct media_stream *strm = entry->user_data; 
    1139  
    1140     PJ_UNUSED_ARG(timer_heap); 
    1141  
    1142     if (!strm->active) 
    1143         return; 
    1144  
    1145     /* Format RTP header */ 
    1146     status = pjmedia_rtp_encode_rtp( &strm->out_sess, strm->si.tx_pt, 
    1147                                      0, /* marker bit */ 
    1148                                      strm->bytes_per_frame,  
    1149                                      strm->samples_per_frame, 
    1150                                      (const void**)&hdr, &hdrlen); 
    1151     if (status == PJ_SUCCESS) { 
    1152  
    1153         //PJ_LOG(4,(THIS_FILE, "\t\tTx seq=%d", pj_ntohs(hdr->seq))); 
    1154  
    1155         /* Copy RTP header to packet */ 
    1156         pj_memcpy(packet, hdr, hdrlen); 
    1157  
    1158         /* Zero the payload */ 
    1159         pj_bzero(packet+hdrlen, strm->bytes_per_frame); 
    1160  
    1161         /* Send RTP packet */ 
    1162         size = hdrlen + strm->bytes_per_frame; 
    1163         status = pjmedia_transport_send_rtp(strm->transport,  
    1164                                             packet, size); 
    1165         if (status != PJ_SUCCESS) 
    1166             app_perror(THIS_FILE, "Error sending RTP packet", status); 
    1167  
    1168     } else { 
    1169         pj_assert(!"RTP encode() error"); 
    1170     } 
    1171  
    1172     /* Update RTCP SR */ 
    1173     pjmedia_rtcp_tx_rtp( &strm->rtcp, (pj_uint16_t)strm->bytes_per_frame); 
    1174  
    1175     /* Schedule next send */ 
    1176     interval.sec = 0; 
    1177     interval.msec = strm->samples_per_frame * 1000 / strm->clock_rate; 
    1178     pj_time_val_normalize(&interval); 
    1179  
    1180     pjsip_endpt_schedule_timer(app.sip_endpt, &strm->rtp_timer, &interval); 
    1181 } 
    1182  
    1183  
    11841105/* 
    11851106 * This callback is called by media transport on receipt of RTCP packet. 
     
    12061127 
    12071128 
    1208 /* This callback is called when it's time to send RTCP packet. */ 
    1209 static void on_tx_rtcp(pj_timer_heap_t *timer_heap, 
    1210                        struct pj_timer_entry *entry) 
    1211 { 
    1212     pjmedia_rtcp_pkt *rtcp_pkt; 
    1213     int rtcp_len; 
    1214     pj_ssize_t size; 
    1215     pj_status_t status; 
    1216     pj_time_val interval; 
    1217     struct media_stream *strm = entry->user_data; 
    1218  
    1219     PJ_UNUSED_ARG(timer_heap); 
    1220  
    1221     if (!strm->active) 
    1222         return; 
    1223  
    1224     /* Build RTCP packet */ 
    1225     pjmedia_rtcp_build_rtcp(&strm->rtcp, &rtcp_pkt, &rtcp_len); 
    1226  
    1227     /* Send packet */ 
    1228     size = rtcp_len; 
    1229     status = pjmedia_transport_send_rtcp(strm->transport, 
    1230                                          rtcp_pkt, size); 
    1231     if (status != PJ_SUCCESS) { 
    1232         app_perror(THIS_FILE, "Error sending RTCP packet", status); 
    1233     } 
     1129/*  
     1130 * Media thread  
     1131 * 
     1132 * This is the thread to send and receive both RTP and RTCP packets. 
     1133 */ 
     1134static int media_thread(void *arg) 
     1135{ 
     1136    enum { RTCP_INTERVAL = 5000, RTCP_RAND = 2000 }; 
     1137    struct media_stream *strm = arg; 
     1138    char packet[1500]; 
     1139    unsigned msec_interval; 
     1140    pj_timestamp freq, next_rtp, next_rtcp; 
     1141 
     1142 
     1143    /* Boost thread priority if necessary */ 
     1144    boost_priority(); 
     1145 
     1146    /* Let things settle */ 
     1147    pj_thread_sleep(1000); 
     1148 
     1149    msec_interval = strm->samples_per_frame * 1000 / strm->clock_rate; 
     1150    pj_get_timestamp_freq(&freq); 
     1151 
     1152    pj_get_timestamp(&next_rtp); 
     1153    next_rtp.u64 += (freq.u64 * msec_interval / 1000); 
     1154 
     1155    next_rtcp = next_rtp; 
     1156    next_rtcp.u64 += (freq.u64 * (RTCP_INTERVAL+(pj_rand()%RTCP_RAND)) / 1000); 
     1157 
     1158 
     1159    while (!strm->thread_quit_flag) { 
     1160        pj_timestamp now, lesser; 
     1161        pj_time_val timeout; 
     1162        pj_bool_t send_rtp, send_rtcp; 
     1163 
     1164        send_rtp = send_rtcp = PJ_FALSE; 
     1165 
     1166        /* Determine how long to sleep */ 
     1167        if (next_rtp.u64 < next_rtcp.u64) { 
     1168            lesser = next_rtp; 
     1169            send_rtp = PJ_TRUE; 
     1170        } else { 
     1171            lesser = next_rtcp; 
     1172            send_rtcp = PJ_TRUE; 
     1173        } 
     1174 
     1175        pj_get_timestamp(&now); 
     1176        if (lesser.u64 <= now.u64) { 
     1177            timeout.sec = timeout.msec = 0; 
     1178            //printf("immediate "); fflush(stdout); 
     1179        } else { 
     1180            pj_uint64_t tick_delay; 
     1181            tick_delay = lesser.u64 - now.u64; 
     1182            timeout.sec = 0; 
     1183            timeout.msec = (pj_uint32_t)(tick_delay * 1000 / freq.u64); 
     1184            pj_time_val_normalize(&timeout); 
     1185 
     1186            //printf("%d:%03d ", timeout.sec, timeout.msec); fflush(stdout); 
     1187        } 
     1188 
     1189        /* Wait for next interval */ 
     1190        //if (timeout.sec!=0 && timeout.msec!=0) { 
     1191            pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout)); 
     1192            if (strm->thread_quit_flag) 
     1193                break; 
     1194        //} 
     1195 
     1196        pj_get_timestamp(&now); 
     1197 
     1198        if (send_rtp || next_rtp.u64 <= now.u64) { 
     1199            /* 
     1200             * Time to send RTP packet. 
     1201             */ 
     1202            pj_status_t status; 
     1203            const pjmedia_rtp_hdr *hdr; 
     1204            pj_ssize_t size; 
     1205            int hdrlen; 
     1206 
     1207            /* Format RTP header */ 
     1208            status = pjmedia_rtp_encode_rtp( &strm->out_sess, strm->si.tx_pt, 
     1209                                             0, /* marker bit */ 
     1210                                             strm->bytes_per_frame,  
     1211                                             strm->samples_per_frame, 
     1212                                             (const void**)&hdr, &hdrlen); 
     1213            if (status == PJ_SUCCESS) { 
     1214 
     1215                //PJ_LOG(4,(THIS_FILE, "\t\tTx seq=%d", pj_ntohs(hdr->seq))); 
     1216 
     1217                /* Copy RTP header to packet */ 
     1218                pj_memcpy(packet, hdr, hdrlen); 
     1219 
     1220                /* Zero the payload */ 
     1221                pj_bzero(packet+hdrlen, strm->bytes_per_frame); 
     1222 
     1223                /* Send RTP packet */ 
     1224                size = hdrlen + strm->bytes_per_frame; 
     1225                status = pjmedia_transport_send_rtp(strm->transport,  
     1226                                                    packet, size); 
     1227                if (status != PJ_SUCCESS) 
     1228                    app_perror(THIS_FILE, "Error sending RTP packet", status); 
     1229 
     1230            } else { 
     1231                pj_assert(!"RTP encode() error"); 
     1232            } 
     1233 
     1234            /* Update RTCP SR */ 
     1235            pjmedia_rtcp_tx_rtp( &strm->rtcp, (pj_uint16_t)strm->bytes_per_frame); 
     1236 
     1237            /* Schedule next send */ 
     1238            next_rtp.u64 += (msec_interval * freq.u64 / 1000); 
     1239        } 
     1240 
     1241 
     1242        if (send_rtcp || next_rtcp.u64 <= now.u64) { 
     1243            /* 
     1244             * Time to send RTCP packet. 
     1245             */ 
     1246            pjmedia_rtcp_pkt *rtcp_pkt; 
     1247            int rtcp_len; 
     1248            pj_ssize_t size; 
     1249            pj_status_t status; 
     1250 
     1251            /* Build RTCP packet */ 
     1252            pjmedia_rtcp_build_rtcp(&strm->rtcp, &rtcp_pkt, &rtcp_len); 
     1253 
    12341254     
    1235     /* Schedule next send */ 
    1236     interval.sec = 5; 
    1237     interval.msec = (pj_rand() % 500); 
    1238     pjsip_endpt_schedule_timer(app.sip_endpt, &strm->rtcp_timer, &interval); 
    1239  
    1240 } 
     1255            /* Send packet */ 
     1256            size = rtcp_len; 
     1257            status = pjmedia_transport_send_rtcp(strm->transport, 
     1258                                                 rtcp_pkt, size); 
     1259            if (status != PJ_SUCCESS) { 
     1260                app_perror(THIS_FILE, "Error sending RTCP packet", status); 
     1261            } 
     1262             
     1263            /* Schedule next send */ 
     1264            next_rtcp.u64 += (freq.u64 * (RTCP_INTERVAL+(pj_rand()%RTCP_RAND)) / 
     1265                              1000); 
     1266        } 
     1267    } 
     1268 
     1269    return 0; 
     1270} 
     1271 
    12411272 
    12421273/* Callback to be called when SDP negotiation is done in the call: */ 
     
    12491280    const pjmedia_sdp_session *local_sdp, *remote_sdp; 
    12501281    struct codec *codec_desc = NULL; 
    1251     pj_time_val interval; 
    12521282    unsigned i; 
    12531283 
     
    12571287 
    12581288    /* If this is a mid-call media update, then destroy existing media */ 
    1259     if (audio->active) 
     1289    if (audio->thread != NULL) 
    12601290        destroy_call_media(call->index); 
    12611291 
     
    13121342    status = pjmedia_transport_attach(audio->transport, audio,  
    13131343                                      &audio->si.rem_addr,  
    1314                                       &audio->si.rem_rtcp, 
     1344                                      &audio->si.rem_rtcp,  
    13151345                                      sizeof(pj_sockaddr_in), 
    13161346                                      &on_rx_rtp, 
     
    13211351    } 
    13221352 
     1353    /* Start media thread. */ 
     1354    audio->thread_quit_flag = 0; 
     1355    status = pj_thread_create( inv->pool, "media", &media_thread, audio, 
     1356                               0, 0, &audio->thread); 
     1357    if (status != PJ_SUCCESS) { 
     1358        app_perror(THIS_FILE, "Error creating media thread", status); 
     1359        return; 
     1360    } 
     1361 
    13231362    /* Set the media as active */ 
    13241363    audio->active = PJ_TRUE; 
    1325  
    1326     /* Immediately schedule to send the first RTP packet. */ 
    1327     audio->rtp_timer.id = 1; 
    1328     interval.sec = interval.msec = 0; 
    1329     pjsip_endpt_schedule_timer(app.sip_endpt, &audio->rtp_timer, &interval); 
    1330  
    1331     /* And schedule the first RTCP packet */ 
    1332     audio->rtcp_timer.id = 1; 
    1333     interval.sec = 4; 
    1334     interval.msec = (pj_rand() % 1000); 
    1335     pjsip_endpt_schedule_timer(app.sip_endpt, &audio->rtcp_timer, &interval); 
    13361364} 
    13371365 
     
    13431371    struct media_stream *audio = &app.call[call_index].media[0]; 
    13441372 
    1345     if (audio->active) { 
     1373    if (audio->thread) { 
    13461374 
    13471375        audio->active = PJ_FALSE; 
    13481376 
    1349         if (audio->rtp_timer.id) { 
    1350             audio->rtp_timer.id = 0; 
    1351             pjsip_endpt_cancel_timer(app.sip_endpt, &audio->rtp_timer); 
    1352         } 
    1353  
    1354         if (audio->rtcp_timer.id) { 
    1355             audio->rtcp_timer.id = 0; 
    1356             pjsip_endpt_cancel_timer(app.sip_endpt, &audio->rtcp_timer); 
    1357         } 
     1377        audio->thread_quit_flag = 1; 
     1378        pj_thread_join(audio->thread); 
     1379        pj_thread_destroy(audio->thread); 
     1380        audio->thread = NULL; 
     1381        audio->thread_quit_flag = 0; 
    13581382 
    13591383        pjmedia_transport_detach(audio->transport, audio); 
     
    13611385} 
    13621386 
    1363  
     1387  
    13641388/***************************************************************************** 
    13651389 * USER INTERFACE STUFFS 
     
    16971721     
    16981722    /* Shutting down... */ 
     1723    destroy_sip(); 
    16991724    destroy_media(); 
    1700     destroy_sip(); 
    17011725 
    17021726    if (app.pool) { 
Note: See TracChangeset for help on using the changeset viewer.