Changeset 3418
- Timestamp:
- Feb 24, 2011 5:14:34 AM (14 years ago)
- 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 135 135 is enabled? */ 136 136 #endif 137 138 pjmedia_vid_codec_info vid_codec_info;139 pjmedia_vid_codec_param *vid_codec_param;140 137 }; 141 138 … … 366 363 void *user_data); 367 364 365 368 366 /** 369 367 * @} -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/stream.c
r3392 r3418 210 210 211 211 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 217 212 }; 218 213 … … 1671 1666 status = pjmedia_jbuf_reset(stream->jb); 1672 1667 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 1731 1668 } else { 1732 1669 /* … … 1990 1927 1991 1928 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 1999 1929 /* 2000 1930 * Create media stream. … … 2017 1947 2018 1948 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 }2030 1949 2031 1950 /* Allocate the media stream: */ … … 2503 2422 pjmedia_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec); 2504 2423 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;2511 2424 } 2512 2425 … … 2826 2739 } 2827 2740 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 != 02842 /* If the interval since last sending packet is greater than2843 * 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 #endif2859 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", because2933 * 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!=02966 /* Update timestamp of last sending packet. */2967 stream->last_frm_ts_sent = frame->timestamp;2968 #endif2969 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 frame2989 * 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_JB3006 trace_jb_get(stream, frame_type, frame_size);3007 #endif3008 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!=03161 stream->use_ka = info->use_ka;3162 #endif3163 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!=03301 /* NAT hole punching by sending KA packet via RTP transport. */3302 if (stream->use_ka)3303 send_keep_alive_packet(stream);3304 #endif3305 3306 #if TRACE_JB3307 {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 #endif3332 3333 /* Init some port-info. Some parts of the info will be set later3334 * 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.