- Timestamp:
- Mar 17, 2011 11:33:34 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c
r3435 r3461 55 55 #endif 56 56 57 #ifndef PJMEDIA_VSTREAM_SIZE 58 # define PJMEDIA_VSTREAM_SIZE 1000 59 #endif 60 61 #ifndef PJMEDIA_VSTREAM_INC 62 # define PJMEDIA_VSTREAM_INC 1000 63 #endif 57 64 58 65 … … 83 90 struct pjmedia_vid_stream 84 91 { 92 pj_pool_t *own_pool; /**< Internal pool. */ 85 93 pjmedia_endpt *endpt; /**< Media endpoint. */ 86 94 pjmedia_vid_codec_mgr *codec_mgr; /**< Codec manager. */ … … 766 774 767 775 while (processed < frame_out.size) { 768 pj_uint8_t *payload, *rtp_pkt; 776 pj_uint8_t *payload; 777 pj_uint8_t *rtp_pkt; 769 778 pj_size_t payload_len; 770 779 … … 775 784 frame_out.size, 776 785 &processed, 777 &payload, &payload_len); 786 (const pj_uint8_t**)&payload, 787 &payload_len); 778 788 if (status != PJ_SUCCESS) { 779 789 LOGERR_((channel->port.info.name.ptr, … … 843 853 pjmedia_vid_channel *channel = stream->dec; 844 854 pjmedia_frame frame_in; 845 pj_ bool_t fps_changed = PJ_FALSE;846 pjmedia_ratio new_fps = {0};855 pj_uint32_t last_ts = 0; 856 int frm_first_seq = 0, frm_last_seq = 0; 847 857 pj_status_t status; 848 858 … … 860 870 char ptype; 861 871 pj_size_t psize, data_len; 862 pj_uint32_t ts , last_ts;872 pj_uint32_t ts; 863 873 int seq; 864 pj_bool_t got_frame , check_fps;874 pj_bool_t got_frame; 865 875 unsigned i; 866 876 867 877 channel->buf_len = 0; 868 last_ts = 0;869 878 got_frame = PJ_FALSE; 870 check_fps = PJ_FALSE;871 879 872 880 /* Lock jitter buffer mutex first */ … … 875 883 for (i=0; ; ++i) { 876 884 /* Get frame from jitter buffer. */ 877 pjmedia_jbuf_peek_frame(stream->jb, i, &p, &psize, &ptype,878 885 pjmedia_jbuf_peek_frame(stream->jb, i, (const void**)&p, 886 &psize, &ptype, NULL, &ts, &seq); 879 887 if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 880 888 if (last_ts == 0) { 881 889 last_ts = ts; 882 check_fps = stream->last_dec_ts && 883 (seq - stream->last_dec_seq == 1) && 884 (last_ts > stream->last_dec_ts); 890 frm_first_seq = seq; 885 891 } 886 892 … … 897 903 data, &data_len); 898 904 channel->buf_len += data_len; 905 frm_last_seq = seq; 899 906 } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 900 907 /* No more packet in the jitter buffer */ … … 911 918 return PJ_SUCCESS; 912 919 } 913 914 /* Learn remote frame rate */915 if (check_fps) {916 pj_uint32_t ts_diff;917 pjmedia_video_format_detail *vfd;918 919 ts_diff = last_ts - stream->last_dec_ts;920 vfd = pjmedia_format_get_video_format_detail(921 &channel->port.info.fmt, PJ_TRUE);922 if (ts_diff * vfd->fps.num !=923 stream->info.codec_info.clock_rate * vfd->fps.denum)924 {925 /* Frame rate changed */926 fps_changed = PJ_TRUE;927 new_fps.num = stream->info.codec_info.clock_rate;928 new_fps.denum = ts_diff;929 }930 }931 932 /* Update last frame seq and timestamp */933 stream->last_dec_seq = seq - 1;934 stream->last_dec_ts = last_ts;935 920 } 936 921 … … 940 925 frame_in.bit_info = 0; 941 926 frame_in.type = PJMEDIA_FRAME_TYPE_VIDEO; 927 frame_in.timestamp.u64 = last_ts; 942 928 943 929 status = stream->codec->op->decode(stream->codec, &frame_in, … … 960 946 } 961 947 962 if (fps_changed) { 963 pjmedia_video_format_detail *vfd; 964 965 /* Update decoding channel port info */ 966 vfd = pjmedia_format_get_video_format_detail( 967 &channel->port.info.fmt, PJ_TRUE); 968 vfd->fps = new_fps; 969 970 /* Update stream info */ 971 vfd = pjmedia_format_get_video_format_detail( 972 &stream->info.codec_param->dec_fmt, PJ_TRUE); 973 vfd->fps = new_fps; 974 975 /* Set bit_info */ 976 frame->bit_info |= PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 977 978 PJ_LOG(4, (channel->port.info.name.ptr, "Frame rate changed to %.2ffps", 979 (1.0 * new_fps.num / new_fps.denum))); 980 } 948 /* Learn remote frame rate after successful decoding */ 949 if (0 && frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size) 950 { 951 /* Only check remote frame rate when timestamp is not wrapping and 952 * sequence is increased by 1. 953 */ 954 if (last_ts > stream->last_dec_ts && 955 frm_first_seq - stream->last_dec_seq == 1) 956 { 957 pj_uint32_t ts_diff; 958 pjmedia_video_format_detail *vfd; 959 960 ts_diff = last_ts - stream->last_dec_ts; 961 vfd = pjmedia_format_get_video_format_detail( 962 &channel->port.info.fmt, PJ_TRUE); 963 if ((int)(stream->info.codec_info.clock_rate / ts_diff) != 964 vfd->fps.num / vfd->fps.denum) 965 { 966 /* Frame rate changed, update decoding port info */ 967 vfd->fps.num = stream->info.codec_info.clock_rate; 968 vfd->fps.denum = ts_diff; 969 970 /* Update stream info */ 971 stream->info.codec_param->dec_fmt.det.vid.fps = vfd->fps; 972 973 /* Set bit_info */ 974 frame->bit_info |= PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 975 976 PJ_LOG(5, (channel->port.info.name.ptr, "Frame rate changed to %.2ffps", 977 (1.0 * vfd->fps.num / vfd->fps.denum))); 978 } 979 } 980 981 /* Update last frame seq and timestamp */ 982 stream->last_dec_seq = frm_last_seq; 983 stream->last_dec_ts = last_ts; 984 } 985 986 #if PJ_LOG_MAX_LEVEL >= 5 987 if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) { 988 pjmedia_port_info *pi = &channel->port.info; 989 990 PJ_LOG(5, (channel->port.info.name.ptr, 991 "Decoding format changed to %dx%d %c%c%c%c %.2ffps", 992 pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h, 993 ((pi->fmt.id & 0x000000FF) >> 0), 994 ((pi->fmt.id & 0x0000FF00) >> 8), 995 ((pi->fmt.id & 0x00FF0000) >> 16), 996 ((pi->fmt.id & 0xFF000000) >> 24), 997 (1.0*pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum))); 998 } 999 #endif 981 1000 982 1001 return PJ_SUCCESS; … … 1001 1020 const char *type_name; 1002 1021 pjmedia_format *fmt; 1022 pjmedia_port_info *pi; 1003 1023 1004 1024 pj_assert(info->type == PJMEDIA_TYPE_VIDEO); … … 1017 1037 fmt = &info->codec_param->enc_fmt; 1018 1038 } 1019 1020 1039 name.ptr = (char*) pj_pool_alloc(pool, M); 1021 1040 name.slen = pj_ansi_snprintf(name.ptr, M, "%s%p", type_name, stream); 1041 pi = &channel->port.info; 1022 1042 1023 1043 /* Init channel info. */ … … 1059 1079 1060 1080 /* Init port. */ 1061 pjmedia_port_info_init2( &channel->port.info, &name,1081 pjmedia_port_info_init2(pi, &name, 1062 1082 PJMEDIA_PORT_SIGNATURE('V', 'C', 'H', 'N'), 1063 1083 dir, fmt); … … 1065 1085 channel->port.get_frame = &get_frame; 1066 1086 } else { 1087 pi->fmt.id = info->codec_param->dec_fmt.id; 1067 1088 channel->port.put_frame = &put_frame; 1068 1089 } … … 1070 1091 /* Init port. */ 1071 1092 channel->port.port_data.pdata = stream; 1093 1094 PJ_LOG(5, (name.ptr, "%s channel created %dx%d %c%c%c%c%s%.*s %.2ffps", 1095 (dir==PJMEDIA_DIR_ENCODING?"Encoding":"Decoding"), 1096 pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h, 1097 ((pi->fmt.id & 0x000000FF) >> 0), 1098 ((pi->fmt.id & 0x0000FF00) >> 8), 1099 ((pi->fmt.id & 0x00FF0000) >> 16), 1100 ((pi->fmt.id & 0xFF000000) >> 24), 1101 (dir==PJMEDIA_DIR_ENCODING?"->":"<-"), 1102 info->codec_info.encoding_name.slen, 1103 info->codec_info.encoding_name.ptr, 1104 (1.0*pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum))); 1072 1105 1073 1106 /* Done. */ … … 1083 1116 pjmedia_endpt *endpt, 1084 1117 pj_pool_t *pool, 1085 constpjmedia_vid_stream_info *info,1118 pjmedia_vid_stream_info *info, 1086 1119 pjmedia_transport *tp, 1087 1120 void *user_data, … … 1089 1122 { 1090 1123 enum { M = 32 }; 1124 pj_pool_t *own_pool = NULL; 1091 1125 pjmedia_vid_stream *stream; 1092 1126 unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len; … … 1096 1130 pj_status_t status; 1097 1131 1132 if (!pool) { 1133 own_pool = pjmedia_endpt_create_pool( endpt, "vstrm%p", 1134 PJMEDIA_VSTREAM_SIZE, 1135 PJMEDIA_VSTREAM_INC); 1136 PJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM); 1137 pool = own_pool; 1138 } 1139 1098 1140 /* Allocate stream */ 1099 1141 stream = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_stream); 1100 1142 PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM); 1101 1102 /* Copy stream info */ 1103 pj_memcpy(&stream->info, info, sizeof(*info)); 1143 stream->own_pool = own_pool; 1104 1144 1105 1145 /* Get codec manager */ … … 1121 1161 1122 1162 /* Get codec param: */ 1123 if (info->codec_param) { 1124 stream->info.codec_param = pjmedia_vid_codec_param_clone( 1125 pool, 1126 info->codec_param); 1127 } else { 1163 if (!info->codec_param) { 1128 1164 pjmedia_vid_codec_param def_param; 1129 1165 … … 1133 1169 if (status != PJ_SUCCESS) 1134 1170 return status; 1135 stream->info.codec_param = pjmedia_vid_codec_param_clone( 1136 pool, 1137 &def_param); 1138 pj_assert(stream->info.codec_param); 1171 1172 info->codec_param = pjmedia_vid_codec_param_clone(pool, &def_param); 1173 pj_assert(info->codec_param); 1139 1174 } 1140 1175 1141 1176 vfd_enc = pjmedia_format_get_video_format_detail( 1142 &stream->info.codec_param->enc_fmt, 1143 PJ_TRUE); 1177 &info->codec_param->enc_fmt, PJ_TRUE); 1144 1178 1145 1179 /* Init stream: */ … … 1174 1208 1175 1209 /* Init codec param */ 1176 stream->info.codec_param->dir = info->dir; 1177 stream->info.codec_param->enc_mtu = PJMEDIA_MAX_MTU - 1178 sizeof(pjmedia_rtp_hdr); 1210 info->codec_param->dir = info->dir; 1211 info->codec_param->enc_mtu = PJMEDIA_MAX_MTU - sizeof(pjmedia_rtp_hdr); 1179 1212 1180 1213 /* Init and open the codec. */ … … 1182 1215 if (status != PJ_SUCCESS) 1183 1216 return status; 1184 status = stream->codec->op->open(stream->codec, stream->info.codec_param);1217 status = stream->codec->op->open(stream->codec, info->codec_param); 1185 1218 if (status != PJ_SUCCESS) 1186 1219 return status; … … 1331 1364 #endif 1332 1365 1366 /* Save the stream info */ 1367 pj_memcpy(&stream->info, info, sizeof(*info)); 1368 stream->info.codec_param = pjmedia_vid_codec_param_clone( 1369 pool, info->codec_param); 1370 1333 1371 /* Success! */ 1334 1372 *p_stream = stream; 1335 1373 1336 PJ_LOG(5,(THIS_FILE, " Stream %s created", stream->name.ptr));1374 PJ_LOG(5,(THIS_FILE, "Video stream %s created", stream->name.ptr)); 1337 1375 1338 1376 return PJ_SUCCESS; … … 1435 1473 #endif 1436 1474 1475 if (stream->own_pool) { 1476 pj_pool_t *pool = stream->own_pool; 1477 stream->own_pool = NULL; 1478 pj_pool_release(pool); 1479 } 1480 1437 1481 return PJ_SUCCESS; 1438 1482 } 1439 1440 1483 1441 1484
Note: See TracChangeset
for help on using the changeset viewer.