Changeset 3418


Ignore:
Timestamp:
Feb 24, 2011 5:14:34 AM (9 years ago)
Author:
nanang
Message:

Re #1182: Reverted back video part in stream.h/c

Location:
pjproject/branches/projects/2.0-dev/pjmedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/stream.h

    r3392 r3418  
    135135                                         is enabled?                        */ 
    136136#endif 
    137  
    138     pjmedia_vid_codec_info       vid_codec_info; 
    139     pjmedia_vid_codec_param     *vid_codec_param; 
    140137}; 
    141138 
     
    366363                                 void *user_data); 
    367364 
     365 
    368366/** 
    369367 * @} 
  • pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/stream.c

    r3392 r3418  
    210210 
    211211    pj_uint32_t              rtp_rx_last_ts;        /**< Last received RTP timestamp*/ 
    212  
    213     pjmedia_vid_codec       *vcodec;                /**< Codec instance being used. */ 
    214     pjmedia_vid_codec_info   vcodec_info;           /**< Codec param.               */ 
    215     pjmedia_vid_codec_param  vcodec_param;          /**< Codec param.               */ 
    216  
    217212}; 
    218213 
     
    16711666        status = pjmedia_jbuf_reset(stream->jb); 
    16721667        PJ_LOG(4,(stream->port.info.name.ptr, "Jitter buffer reset")); 
    1673  
    1674     } else if (stream->vcodec) { 
    1675         pj_timestamp ts; 
    1676         pj_uint8_t *p; 
    1677         pj_size_t p_len; 
    1678  
    1679         /* Video stream */ 
    1680  
    1681         ts.u64 = pj_ntohl(hdr->ts); 
    1682  
    1683         /* Put any buffered bitstream if timestamp is changed, 
    1684          * in case of RTP packet lost. 
    1685          */ 
    1686         if (stream->rtp_rx_last_ts != ts.u64 && channel->out_pkt_len) 
    1687         { 
    1688             int seq; 
    1689  
    1690             seq = stream->rtp_rx_last_ts/stream->rtp_rx_ts_len_per_frame; 
    1691             pjmedia_jbuf_put_frame(stream->jb, channel->out_pkt, 
    1692                                    channel->out_pkt_len, seq); 
    1693             channel->out_pkt_len = 0; 
    1694         } 
    1695  
    1696         p = (pj_uint8_t*)channel->out_pkt + channel->out_pkt_len; 
    1697         p_len = channel->out_pkt_size - channel->out_pkt_len; 
    1698  
    1699         /* Parse the payload. */ 
    1700         status = (*stream->vcodec->op->unpacketize)( 
    1701                                             stream->vcodec, 
    1702                                             payload, payloadlen, 
    1703                                             p, &p_len); 
    1704         if (status != PJ_SUCCESS) { 
    1705             LOGERR_((stream->port.info.name.ptr,  
    1706                      "Codec parse() error",  
    1707                      status)); 
    1708             channel->out_pkt_len = 0; 
    1709         } else { 
    1710             channel->out_pkt_len += p_len; 
    1711             if (channel->out_pkt_len > channel->out_pkt_size) { 
    1712                 channel->out_pkt_len = channel->out_pkt_size; 
    1713                 PJ_LOG(3, (THIS_FILE, "Video bitstream trucated because of" 
    1714                            "not enough buffer")); 
    1715             } 
    1716  
    1717             /* Check if RTP header specifies end of frame mark */ 
    1718             PJ_TODO(find_better_way_to_find_out_end_of_frame_mark); 
    1719             if (hdr->m) { 
    1720                 int seq; 
    1721  
    1722                 seq = (int)(ts.u64/stream->rtp_rx_ts_len_per_frame); 
    1723                 pjmedia_jbuf_put_frame(stream->jb, channel->out_pkt, 
    1724                                        channel->out_pkt_len, seq); 
    1725                 channel->out_pkt_len = 0; 
    1726             } 
    1727         } 
    1728  
    1729         stream->rtp_rx_last_ts = (pj_uint32_t)ts.u64; 
    1730          
    17311668    } else { 
    17321669        /* 
     
    19901927 
    19911928 
    1992 static pj_status_t video_stream_create(pjmedia_endpt *endpt, 
    1993                                        pj_pool_t *pool, 
    1994                                        const pjmedia_stream_info *info, 
    1995                                        pjmedia_transport *tp, 
    1996                                        void *user_data, 
    1997                                        pjmedia_stream **p_stream); 
    1998  
    19991929/* 
    20001930 * Create media stream. 
     
    20171947 
    20181948    PJ_ASSERT_RETURN(pool && info && p_stream, PJ_EINVAL); 
    2019  
    2020  
    2021     if (info->type == PJMEDIA_TYPE_VIDEO) { 
    2022         status = video_stream_create(endpt, pool, info, tp,  
    2023                                      user_data, &stream); 
    2024         if (status != PJ_SUCCESS) 
    2025             goto err_cleanup; 
    2026  
    2027         *p_stream = stream; 
    2028         return PJ_SUCCESS; 
    2029     } 
    20301949 
    20311950    /* Allocate the media stream: */ 
     
    25032422        pjmedia_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec); 
    25042423        stream->codec = NULL; 
    2505     } 
    2506  
    2507     if (stream->vcodec) { 
    2508         stream->vcodec->op->close(stream->vcodec); 
    2509         pjmedia_vid_codec_mgr_dealloc_codec(NULL, stream->vcodec); 
    2510         stream->vcodec = NULL; 
    25112424    } 
    25122425 
     
    28262739} 
    28272740 
    2828 static pj_status_t put_vid_frame(pjmedia_port *port, 
    2829                                  pjmedia_frame *frame) 
    2830 { 
    2831     pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata; 
    2832     pjmedia_channel *channel = stream->enc; 
    2833     pj_status_t status = 0; 
    2834     pjmedia_frame frame_out; 
    2835     unsigned rtp_ts_len; 
    2836     void *rtphdr; 
    2837     int rtphdrlen; 
    2838     unsigned processed = 0; 
    2839  
    2840  
    2841 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0 
    2842     /* If the interval since last sending packet is greater than 
    2843      * PJMEDIA_STREAM_KA_INTERVAL, send keep-alive packet. 
    2844      */ 
    2845     if (stream->use_ka) 
    2846     { 
    2847         pj_uint32_t dtx_duration; 
    2848  
    2849         dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent,  
    2850                                            &frame->timestamp); 
    2851         if (dtx_duration > 
    2852             PJMEDIA_STREAM_KA_INTERVAL * stream->port.info.clock_rate) 
    2853         { 
    2854             send_keep_alive_packet(stream); 
    2855             stream->last_frm_ts_sent = frame->timestamp; 
    2856         } 
    2857     } 
    2858 #endif 
    2859  
    2860     /* Don't do anything if stream is paused */ 
    2861     if (channel->paused) { 
    2862         stream->enc_buf_pos = stream->enc_buf_count = 0; 
    2863         return PJ_SUCCESS; 
    2864     } 
    2865  
    2866     /* Increment transmit duration */ 
    2867     rtp_ts_len = stream->rtp_tx_ts_len_per_pkt; 
    2868     stream->tx_duration += rtp_ts_len; 
    2869  
    2870     /* Init frame_out buffer. */ 
    2871     frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr); 
    2872     frame_out.size = 0; 
    2873  
    2874     /* Encode! */ 
    2875     status = (*stream->vcodec->op->encode)(stream->vcodec, frame,  
    2876                                            channel->out_pkt_size -  
    2877                                            sizeof(pjmedia_rtp_hdr), 
    2878                                            &frame_out); 
    2879     if (status != PJ_SUCCESS) { 
    2880         LOGERR_((stream->port.info.name.ptr,  
    2881                 "Codec encode() error", status)); 
    2882         return status; 
    2883     } 
    2884  
    2885  
    2886     while (processed < frame_out.size) { 
    2887         pj_uint8_t *payload, *rtp_pkt; 
    2888         pj_size_t payload_len; 
    2889  
    2890         /* Generate RTP payload */ 
    2891         status = (*stream->vcodec->op->packetize)( 
    2892                                            stream->vcodec, 
    2893                                            (pj_uint8_t*)frame_out.buf, 
    2894                                            frame_out.size, 
    2895                                            &processed, 
    2896                                            &payload, &payload_len); 
    2897         if (status != PJ_SUCCESS) { 
    2898             LOGERR_((stream->port.info.name.ptr,  
    2899                     "Codec pack() error", status)); 
    2900             return status; 
    2901         } 
    2902  
    2903         /* Encapsulate. */ 
    2904         status = pjmedia_rtp_encode_rtp( &channel->rtp,  
    2905                                          channel->pt, 
    2906                                          (processed==frame_out.size?1:0), 
    2907                                          payload_len, 
    2908                                          rtp_ts_len,  
    2909                                          (const void**)&rtphdr,  
    2910                                          &rtphdrlen); 
    2911  
    2912         if (status != PJ_SUCCESS) { 
    2913             LOGERR_((stream->port.info.name.ptr,  
    2914                     "RTP encode_rtp() error", status)); 
    2915             return status; 
    2916         } 
    2917  
    2918         /* Next packets use same timestamp */ 
    2919         rtp_ts_len = 0; 
    2920  
    2921         rtp_pkt = payload - sizeof(pjmedia_rtp_hdr); 
    2922  
    2923         /* Copy RTP header to the beginning of packet */ 
    2924         pj_memcpy(rtp_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); 
    2925  
    2926         /* Send the RTP packet to the transport. */ 
    2927         pjmedia_transport_send_rtp(stream->transport, rtp_pkt,  
    2928                                    payload_len + sizeof(pjmedia_rtp_hdr)); 
    2929     } 
    2930  
    2931     /* Check if now is the time to transmit RTCP SR/RR report.  
    2932      * We only do this when stream direction is not "decoding only", because 
    2933      * when it is, check_tx_rtcp() will be handled by get_frame(). 
    2934      */ 
    2935     if (stream->dir != PJMEDIA_DIR_DECODING) { 
    2936         check_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts)); 
    2937     } 
    2938  
    2939     /* Do nothing if we have nothing to transmit */ 
    2940     if (frame_out.size == 0) { 
    2941         if (stream->is_streaming) { 
    2942             PJ_LOG(5,(stream->port.info.name.ptr,"Starting silence")); 
    2943             stream->is_streaming = PJ_FALSE; 
    2944         } 
    2945  
    2946         return PJ_SUCCESS; 
    2947     } 
    2948  
    2949  
    2950     /* Set RTP marker bit if currently not streaming */ 
    2951     if (stream->is_streaming == PJ_FALSE) { 
    2952         // RTP header M in video packet is usually for end of frame flag. 
    2953         //pjmedia_rtp_hdr *rtp = (pjmedia_rtp_hdr*) channel->out_pkt; 
    2954         //rtp->m = 1; 
    2955         PJ_LOG(5,(stream->port.info.name.ptr,"Start talksprut..")); 
    2956     } 
    2957  
    2958     stream->is_streaming = PJ_TRUE; 
    2959  
    2960     /* Update stat */ 
    2961     pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size); 
    2962     stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts); 
    2963     stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq); 
    2964  
    2965 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 
    2966     /* Update timestamp of last sending packet. */ 
    2967     stream->last_frm_ts_sent = frame->timestamp; 
    2968 #endif 
    2969  
    2970     return PJ_SUCCESS; 
    2971 } 
    2972  
    2973 static pj_status_t get_vid_frame(pjmedia_port *port, 
    2974                                  pjmedia_frame *frame) 
    2975 { 
    2976     pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata; 
    2977     pjmedia_channel *channel = stream->dec; 
    2978     pj_uint8_t *p_out_samp; 
    2979     pj_status_t status; 
    2980  
    2981  
    2982     /* Return no frame is channel is paused */ 
    2983     if (channel->paused) { 
    2984         frame->type = PJMEDIA_FRAME_TYPE_NONE; 
    2985         return PJ_SUCCESS; 
    2986     } 
    2987  
    2988     /* Repeat get frame from the jitter buffer and decode the frame 
    2989      * until we have enough frames according to codec's ptime. 
    2990      */ 
    2991  
    2992     /* Lock jitter buffer mutex first */ 
    2993     pj_mutex_lock( stream->jb_mutex ); 
    2994  
    2995     p_out_samp = (pj_uint8_t*) frame->buf; 
    2996     { 
    2997         char frame_type; 
    2998         pj_size_t frame_size; 
    2999         pj_uint32_t bit_info; 
    3000  
    3001         /* Get frame from jitter buffer. */ 
    3002         pjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size, 
    3003                                 &frame_type, &bit_info); 
    3004  
    3005 #if TRACE_JB 
    3006         trace_jb_get(stream, frame_type, frame_size); 
    3007 #endif 
    3008  
    3009         if (frame_type != PJMEDIA_JB_NORMAL_FRAME) { 
    3010             const char *with_plc = ""; 
    3011              
    3012             /* Activate PLC */ 
    3013             if (stream->vcodec->op->recover &&  
    3014                 //stream->codec_param.setting.plc && 
    3015                 stream->plc_cnt < stream->max_plc_cnt)  
    3016             { 
    3017                 status = (*stream->codec->op->recover)(stream->codec, 
    3018                                                        frame->size, 
    3019                                                        frame); 
    3020  
    3021                 ++stream->plc_cnt; 
    3022                 with_plc = ", plc invoked"; 
    3023             } else { 
    3024                 status = -1; 
    3025             } 
    3026  
    3027             if (status != PJ_SUCCESS) { 
    3028                 /* Either PLC failed or PLC not supported/enabled */ 
    3029                 //pjmedia_zero_samples(p_out_samp + samples_count, 
    3030                 //                   samples_required - samples_count); 
    3031                 frame->size = 0; 
    3032             } 
    3033  
    3034             if (frame_type != stream->jb_last_frm) { 
    3035                 if (frame_type == PJMEDIA_JB_MISSING_FRAME) { 
    3036                     pjmedia_jb_state jb_state; 
    3037  
    3038                     /* Report changing frame type event */ 
    3039                     pjmedia_jbuf_get_state(stream->jb, &jb_state); 
    3040                     PJ_LOG(5,(stream->port.info.name.ptr,  
    3041                               "Jitter buffer empty (prefetch=%d)%s",  
    3042                               jb_state.prefetch, with_plc)); 
    3043                 } else { 
    3044                     /* Report changing frame type event */ 
    3045                     PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost%s!", 
    3046                               (status == PJ_SUCCESS? ", recovered":""))); 
    3047                 } 
    3048  
    3049                 stream->jb_last_frm = frame_type; 
    3050                 stream->jb_last_frm_cnt = 1; 
    3051             } else { 
    3052                 stream->jb_last_frm_cnt++; 
    3053             } 
    3054  
    3055         } else { 
    3056             /* Got "NORMAL" frame from jitter buffer */ 
    3057             pjmedia_frame frame_in, frame_out; 
    3058  
    3059             stream->plc_cnt = 0; 
    3060  
    3061             /* Decode */ 
    3062             frame_in.buf = channel->out_pkt; 
    3063             frame_in.size = frame_size; 
    3064             frame_in.bit_info = bit_info; 
    3065             frame_in.type = PJMEDIA_FRAME_TYPE_VIDEO;  /* ignored */ 
    3066  
    3067             frame_out.buf = p_out_samp; 
    3068             frame_out.size = frame->size; 
    3069             status = stream->vcodec->op->decode(stream->vcodec, &frame_in, 
    3070                                                 frame_out.size, &frame_out); 
    3071             if (status != 0) { 
    3072                 LOGERR_((port->info.name.ptr, "codec decode() error",  
    3073                          status)); 
    3074  
    3075                 //pjmedia_zero_samples(p_out_samp + samples_count,  
    3076                 //                   samples_per_frame); 
    3077                 frame_out.size = 0; 
    3078             } 
    3079  
    3080             if (stream->jb_last_frm != frame_type) { 
    3081                 /* Report changing frame type event */ 
    3082                 PJ_LOG(5,(stream->port.info.name.ptr,  
    3083                           "Jitter buffer starts returning normal frames " 
    3084                           "(after %d empty/lost)", 
    3085                           stream->jb_last_frm_cnt, stream->jb_last_frm)); 
    3086  
    3087                 stream->jb_last_frm = frame_type; 
    3088                 stream->jb_last_frm_cnt = 1; 
    3089             } else { 
    3090                 stream->jb_last_frm_cnt++; 
    3091             } 
    3092  
    3093             frame->size = frame_out.size; 
    3094         } 
    3095     } 
    3096  
    3097  
    3098     /* Unlock jitter buffer mutex. */ 
    3099     pj_mutex_unlock( stream->jb_mutex ); 
    3100  
    3101     return PJ_SUCCESS; 
    3102 } 
    3103  
    3104 static pj_status_t video_stream_create(pjmedia_endpt *endpt, 
    3105                                        pj_pool_t *pool, 
    3106                                        const pjmedia_stream_info *info, 
    3107                                        pjmedia_transport *tp, 
    3108                                        void *user_data, 
    3109                                        pjmedia_stream **p_stream) 
    3110 { 
    3111     enum { M = 32 }; 
    3112     pjmedia_stream *stream; 
    3113     pj_str_t name; 
    3114     unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len; 
    3115     pjmedia_video_format_detail *vfd_enc; 
    3116     char *p; 
    3117     pj_status_t status; 
    3118  
    3119     stream = PJ_POOL_ZALLOC_T(pool, pjmedia_stream); 
    3120     PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM); 
    3121     PJ_ASSERT_RETURN(pjmedia_vid_codec_mgr_instance(), PJMEDIA_CODEC_EFAILED); 
    3122  
    3123     /* Init stream/port name */ 
    3124     name.ptr = (char*) pj_pool_alloc(pool, M); 
    3125     name.slen = pj_ansi_snprintf(name.ptr, M, "vstrm%p", stream); 
    3126  
    3127     /* Create and initialize codec: */ 
    3128     stream->vcodec_info = info->vid_codec_info; 
    3129     status = pjmedia_vid_codec_mgr_alloc_codec(NULL, &info->vid_codec_info, 
    3130                                                &stream->vcodec); 
    3131     if (status != PJ_SUCCESS) 
    3132         return status; 
    3133  
    3134  
    3135     /* Get codec param: */ 
    3136     if (info->vid_codec_param) 
    3137         stream->vcodec_param = *info->vid_codec_param; 
    3138     else { 
    3139         status = pjmedia_vid_codec_mgr_get_default_param(NULL,  
    3140                                                          &info->vid_codec_info, 
    3141                                                          &stream->vcodec_param); 
    3142         if (status != PJ_SUCCESS) 
    3143             return status; 
    3144     } 
    3145  
    3146     vfd_enc = pjmedia_format_get_video_format_detail( 
    3147                                             &stream->vcodec_param.enc_fmt, 1); 
    3148  
    3149     /* Init stream: */ 
    3150     stream->endpt = endpt; 
    3151     stream->dir = info->dir; 
    3152     stream->user_data = user_data; 
    3153     stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) * 
    3154                             info->vid_codec_info.clock_rate / 1000; 
    3155  
    3156     stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME; 
    3157     stream->tx_event_pt = -1; 
    3158     stream->rx_event_pt = -1; 
    3159  
    3160 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 
    3161     stream->use_ka = info->use_ka; 
    3162 #endif 
    3163  
    3164     /* Build random RTCP CNAME. CNAME has user@host format */ 
    3165     stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); 
    3166     pj_create_random_string(p, 5); 
    3167     p += 5; 
    3168     *p++ = '@'; *p++ = 'p'; *p++ = 'j'; 
    3169     pj_create_random_string(p, 6); 
    3170     p += 6; 
    3171     *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g'; 
    3172     stream->cname.slen = p - stream->cname.ptr; 
    3173  
    3174  
    3175     /* Create mutex to protect jitter buffer: */ 
    3176  
    3177     status = pj_mutex_create_simple(pool, NULL, &stream->jb_mutex); 
    3178     if (status != PJ_SUCCESS) 
    3179         return status; 
    3180  
    3181     /* Check for invalid max_bps. */ 
    3182  //   if (stream->codec_param.info.max_bps < stream->codec_param.info.avg_bps) 
    3183         //stream->codec_param.info.max_bps = stream->codec_param.info.avg_bps; 
    3184  
    3185     /* Check for invalid frame per packet. */ 
    3186  //   if (stream->codec_param.setting.frm_per_pkt < 1) 
    3187         //stream->codec_param.setting.frm_per_pkt = 1; 
    3188  
    3189     /* Open the codec. */ 
    3190     stream->vcodec_param.dir = info->dir; 
    3191     stream->vcodec_param.enc_mtu = PJMEDIA_MAX_MTU - 40; 
    3192     status = stream->vcodec->op->init(stream->vcodec, pool); 
    3193     if (status != PJ_SUCCESS) 
    3194         return status; 
    3195     status = stream->vcodec->op->open(stream->vcodec, &stream->vcodec_param); 
    3196     if (status != PJ_SUCCESS) 
    3197         return status; 
    3198  
    3199     /* Set additional info and callbacks. */ 
    3200     stream->port.put_frame = &put_vid_frame; 
    3201     stream->port.get_frame = &get_vid_frame; 
    3202  
    3203     /* Get the frame size */ 
    3204     //stream->frame_size = vfd_enc->max_bps * 
    3205     //                     vfd_enc->fps.denum / vfd_enc->fps.num; 
    3206     stream->frame_size = 128000; 
    3207  
    3208     /* How many consecutive PLC frames can be generated */ 
    3209     stream->max_plc_cnt = MAX_PLC_MSEC * 
    3210                           vfd_enc->fps.num / vfd_enc->fps.denum / 1000; 
    3211  
    3212     stream->rtp_rx_check_cnt = 5; 
    3213     stream->rtp_rx_last_ts = 0; 
    3214     stream->rtp_rx_last_cnt = 0; 
    3215     stream->rtp_tx_ts_len_per_pkt =  
    3216                             info->vid_codec_info.clock_rate * 
    3217                             vfd_enc->fps.denum / vfd_enc->fps.num; 
    3218     stream->rtp_rx_ts_len_per_frame = stream->rtp_tx_ts_len_per_pkt; 
    3219  
    3220     /* Init jitter buffer parameters: */ 
    3221     jb_max     = info->jb_max * 
    3222                  vfd_enc->fps.num / vfd_enc->fps.denum / 1000; 
    3223     jb_min_pre = info->jb_min_pre * 
    3224                  vfd_enc->fps.num / vfd_enc->fps.denum / 1000; 
    3225     jb_max_pre = info->jb_max_pre * 
    3226                  vfd_enc->fps.num / vfd_enc->fps.denum / 1000; 
    3227     jb_init    = info->jb_init * 
    3228                  vfd_enc->fps.num / vfd_enc->fps.denum / 1000; 
    3229  
    3230     /* When JB max frame count==0, set to 0.5s */ 
    3231     if (jb_max == 0) 
    3232         jb_max = (vfd_enc->fps.num + vfd_enc->fps.denum/2) / 
    3233                   vfd_enc->fps.denum / 2; 
    3234      
    3235     /* When JB max prefetch==0, set to (4/5 * jb_max) */ 
    3236     if (jb_max_pre == 0) 
    3237         jb_max_pre = jb_max * 4 / 5; 
    3238  
    3239     /* Create jitter buffer */ 
    3240     status = pjmedia_jbuf_create(pool, &stream->port.info.name, 
    3241                                  stream->frame_size,  
    3242                                  1000 * vfd_enc->fps.denum / vfd_enc->fps.num, 
    3243                                  jb_max, &stream->jb); 
    3244     if (status != PJ_SUCCESS) 
    3245         return status; 
    3246  
    3247  
    3248     /* Set up jitter buffer */ 
    3249     pjmedia_jbuf_set_adaptive( stream->jb, jb_init, jb_min_pre, jb_max_pre); 
    3250  
    3251     /* Create decoder channel: */ 
    3252  
    3253     status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,  
    3254                              stream->vcodec_param.pt, info, &stream->dec); 
    3255     if (status != PJ_SUCCESS) 
    3256         return status; 
    3257  
    3258  
    3259     /* Create encoder channel: */ 
    3260  
    3261     status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING,  
    3262                              info->tx_pt, info, &stream->enc); 
    3263     if (status != PJ_SUCCESS) 
    3264         return status; 
    3265  
    3266  
    3267     /* Init RTCP session: */ 
    3268  
    3269     { 
    3270         pjmedia_rtcp_session_setting rtcp_setting; 
    3271  
    3272         pjmedia_rtcp_session_setting_default(&rtcp_setting); 
    3273         rtcp_setting.name = stream->port.info.name.ptr; 
    3274         rtcp_setting.ssrc = info->ssrc; 
    3275         rtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts); 
    3276         rtcp_setting.clock_rate = info->vid_codec_info.clock_rate; 
    3277         rtcp_setting.samples_per_frame = stream->rtp_tx_ts_len_per_pkt; 
    3278  
    3279         pjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting); 
    3280     } 
    3281  
    3282     /* Only attach transport when stream is ready. */ 
    3283     status = pjmedia_transport_attach(tp, stream, &info->rem_addr,  
    3284                                       &info->rem_rtcp,  
    3285                                       pj_sockaddr_get_len(&info->rem_addr),  
    3286                                       &on_rx_rtp, &on_rx_rtcp); 
    3287     if (status != PJ_SUCCESS) 
    3288         return status; 
    3289  
    3290     stream->transport = tp; 
    3291  
    3292     /* Send RTCP SDES */ 
    3293     len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->out_pkt,  
    3294                            stream->enc->out_pkt_size); 
    3295     if (len != 0) { 
    3296         pjmedia_transport_send_rtcp(stream->transport,  
    3297                                     stream->enc->out_pkt, len); 
    3298     } 
    3299  
    3300 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0 
    3301     /* NAT hole punching by sending KA packet via RTP transport. */ 
    3302     if (stream->use_ka) 
    3303         send_keep_alive_packet(stream); 
    3304 #endif 
    3305  
    3306 #if TRACE_JB 
    3307     { 
    3308         char trace_name[PJ_MAXPATH]; 
    3309         pj_ssize_t len; 
    3310  
    3311         pj_ansi_snprintf(trace_name, sizeof(trace_name),  
    3312                          TRACE_JB_PATH_PREFIX "%s.csv", 
    3313                          stream->port.info.name.ptr); 
    3314         status = pj_file_open(pool, trace_name, PJ_O_RDWR, &stream->trace_jb_fd); 
    3315         if (status != PJ_SUCCESS) { 
    3316             stream->trace_jb_fd = TRACE_JB_INVALID_FD; 
    3317             PJ_LOG(3,(THIS_FILE, "Failed creating RTP trace file '%s'",  
    3318                       trace_name)); 
    3319         } else { 
    3320             stream->trace_jb_buf = (char*)pj_pool_alloc(pool, PJ_LOG_MAX_SIZE); 
    3321  
    3322             /* Print column header */ 
    3323             len = pj_ansi_snprintf(stream->trace_jb_buf, PJ_LOG_MAX_SIZE, 
    3324                                    "Time, Operation, Size, Frame Count, " 
    3325                                    "Frame type, RTP Seq, RTP TS, RTP M, " 
    3326                                    "JB size, JB burst level, JB prefetch\n"); 
    3327             pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len); 
    3328             pj_file_flush(stream->trace_jb_fd); 
    3329         } 
    3330     } 
    3331 #endif 
    3332  
    3333     /* Init some port-info. Some parts of the info will be set later 
    3334      * once we have more info about the codec. 
    3335      */ 
    3336     pjmedia_port_info_init2(&stream->port.info, &name, 
    3337                             PJMEDIA_PORT_SIGNATURE('S', 'T', 'R', 'M'), 
    3338                             info->dir, &stream->vcodec_param.dec_fmt); 
    3339  
    3340     /* Init port. */ 
    3341     stream->port.port_data.pdata = stream; 
    3342  
    3343     /* Success! */ 
    3344     *p_stream = stream; 
    3345  
    3346     PJ_LOG(5,(THIS_FILE, "Stream %s created", stream->port.info.name.ptr)); 
    3347  
    3348     return PJ_SUCCESS; 
    3349 } 
Note: See TracChangeset for help on using the changeset viewer.