- Timestamp:
- Feb 9, 2009 10:39:58 AM (16 years ago)
- Location:
- pjproject/branches/projects/aps-direct
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-codec/amr_helper.h
r2394 r2444 633 633 * @return AMR mode. 634 634 */ 635 636 635 PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode(unsigned bitrate) 637 636 { … … 679 678 680 679 /** 680 * Get AMR mode based on frame length. 681 * 682 * @param amrnb Set to PJ_TRUE for AMR-NB domain or PJ_FALSE for AMR-WB. 683 * @param frame_len The frame length. 684 * 685 * @return AMR mode. 686 */ 687 688 PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode2(pj_bool_t amrnb, 689 unsigned frame_len) 690 { 691 unsigned i; 692 693 if (amrnb) { 694 for (i = 0; i < 9; ++i) 695 if (frame_len == pjmedia_codec_amrnb_framelen[i]) 696 return i; 697 } else { 698 for (i = 0; i < 10; ++i) { 699 if (frame_len == pjmedia_codec_amrwb_framelen[i]) 700 return i; 701 } 702 } 703 704 pj_assert(!"Invalid AMR frame length"); 705 return -1; 706 } 707 708 /** 681 709 * Prepare a frame before pass it to decoder. This function will do: 682 710 * - reorder AMR bitstream from descending sensitivity order into -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/port.h
r2439 r2444 311 311 pjmedia_frame_ext_subframe *fsub; 312 312 fsub = (pjmedia_frame_ext_subframe*) p; 313 p += sizeof(fsub->bitlen) + fsub->bitlen / 8;314 if (fsub->bitlen % 8)313 p += sizeof(fsub->bitlen) + (fsub->bitlen >> 3); 314 if (fsub->bitlen & 0x07) 315 315 ++p; 316 316 } 317 317 318 tmp = bitlen / 8; 319 if (bitlen % 8) ++tmp; 318 tmp = bitlen >> 3; 319 if (bitlen & 0x07) 320 ++tmp; 320 321 321 322 pj_memcpy(p, &bitlen, sizeof(bitlen)); … … 348 349 for (i = 0; i < n; ++i) { 349 350 sf = (pjmedia_frame_ext_subframe*) p; 350 p += sizeof(sf->bitlen) + sf->bitlen / 8;351 if (sf->bitlen % 8)351 p += sizeof(sf->bitlen) + (sf->bitlen >> 3); 352 if (sf->bitlen & 0x07) 352 353 ++p; 353 354 } … … 382 383 move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n); 383 384 sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1); 384 move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) + sf->bitlen/8; 385 if (sf->bitlen % 8 != 0) 385 move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) + 386 (sf->bitlen >> 3); 387 if (sf->bitlen & 0x07) 386 388 ++move_len; 387 389 pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext), -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/types.h
r2438 r2444 201 201 #define PJMEDIA_FOURCC_AMR PJMEDIA_FOURCC_PACK(' ', 'A', 'M', 'R') 202 202 #define PJMEDIA_FOURCC_G729 PJMEDIA_FOURCC_PACK('G', '7', '2', '9') 203 #define PJMEDIA_FOURCC_ILBC PJMEDIA_FOURCC_PACK(' i', 'L', 'B', 'C')203 #define PJMEDIA_FOURCC_ILBC PJMEDIA_FOURCC_PACK('I', 'L', 'B', 'C') 204 204 205 205 -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-codec/passthrough.c
r2438 r2444 171 171 { 172 172 # if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 173 {1, "AMR", PJMEDIA_RTP_PT_AMR, PJMEDIA_FOURCC_AMR,173 {1, "AMR", PJMEDIA_RTP_PT_AMR, {PJMEDIA_FOURCC_AMR}, 174 174 8000, 1, 160, 175 5900, 12200, 4,175 12200, 12200, 2, 176 176 &parse_amr, &pack_amr 177 177 /*, {1, {{{"octet-align", 11}, {"1", 1}}} } */ … … 180 180 181 181 # if PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 182 {1, "G729", PJMEDIA_RTP_PT_G729, PJMEDIA_FOURCC_G729,182 {1, "G729", PJMEDIA_RTP_PT_G729, {PJMEDIA_FOURCC_G729}, 183 183 8000, 1, 80, 184 8000, 11800, 2184 8000, 8000, 2 185 185 }, 186 186 # endif 187 187 188 188 # if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 189 {1, "iLBC", PJMEDIA_RTP_PT_ILBC, PJMEDIA_FOURCC_ILBC,190 8000, 1, 80,191 8000, 11800, 2,189 {1, "iLBC", PJMEDIA_RTP_PT_ILBC, {PJMEDIA_FOURCC_ILBC}, 190 8000, 1, 240, 191 13333, 15200, 2, 192 192 NULL, NULL, 193 193 {1, {{{"mode", 4}, {"30", 2}}} } … … 196 196 197 197 # if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 198 {1, "PCMU", PJMEDIA_RTP_PT_PCMU, PJMEDIA_FOURCC_G711U,198 {1, "PCMU", PJMEDIA_RTP_PT_PCMU, {PJMEDIA_FOURCC_G711U}, 199 199 8000, 1, 80, 200 200 64000, 64000, 2 … … 203 203 204 204 # if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 205 {1, "PCMA", PJMEDIA_RTP_PT_PCMA, PJMEDIA_FOURCC_G711A,205 {1, "PCMA", PJMEDIA_RTP_PT_PCMA, {PJMEDIA_FOURCC_G711A}, 206 206 8000, 1, 80, 207 207 64000, 64000, 2 … … 210 210 }; 211 211 212 212 213 #if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 213 214 … … 227 228 struct pjmedia_frame *output) 228 229 { 229 enum {MAX_FRAMES_PER_PACKET = 16};230 enum {MAX_FRAMES_PER_PACKET = 8}; 230 231 231 232 pjmedia_frame frames[MAX_FRAMES_PER_PACKET]; 232 unsigned nframes = 0; 233 pjmedia_codec_amr_bit_info *info; 234 235 PJ_TODO(DEFINE_AMR_FRAME_INFO_FOR_PJMEDIA_FRAME_EXT); 236 237 #if 0 238 239 pj_uint8_t *r; /* Read cursor */ 233 amr_settings_t* setting = (amr_settings_t*)codec_data->codec_setting; 234 pjmedia_codec_amr_pack_setting *enc_setting = &setting->enc_setting; 240 235 pj_uint8_t SID_FT; 241 pjmedia_codec_amr_pack_setting *setting; 242 243 setting = &((amr_settings_t*)codec_data->codec_setting)->enc_setting; 244 245 SID_FT = (pj_uint8_t)(setting->amr_nb? 8 : 9); 246 247 /* Align pkt buf right */ 248 r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size; 249 pj_memmove(r, pkt, *pkt_size); 236 unsigned i; 237 238 pj_assert(input->subframe_cnt <= MAX_FRAMES_PER_PACKET); 239 240 SID_FT = (pj_uint8_t)(enc_setting->amr_nb? 8 : 9); 250 241 251 242 /* Get frames */ 252 for (;;) { 253 pj_bool_t eof; 254 pj_uint16_t info_; 255 256 info_ = *((pj_uint16_t*)r); 257 eof = ((info_ & 0x40) != 0); 258 259 info = (pjmedia_codec_amr_bit_info*) &frames[nframes].bit_info; 243 for (i = 0; i < input->subframe_cnt; ++i) { 244 pjmedia_frame_ext_subframe *sf; 245 pjmedia_codec_amr_bit_info *info; 246 unsigned len; 247 248 sf = pjmedia_frame_ext_get_subframe(input, i); 249 250 len = sf->bitlen >> 3; 251 if (sf->bitlen & 0x07) 252 ++len; 253 254 info = (pjmedia_codec_amr_bit_info*) &frames[i].bit_info; 260 255 pj_bzero(info, sizeof(*info)); 261 info->frame_type = (pj_uint8_t)(info_ & 0x0F); 256 info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb, 257 len); 262 258 info->good_quality = 1; 263 info->mode = (pj_int8_t) ((info_ >> 8) & 0x0F); 264 265 frames[nframes].buf = r + 2; 266 frames[nframes].size = info->frame_type <= SID_FT ? 267 pjmedia_codec_amrnb_framelen[info->frame_type] : 268 0; 269 270 r += frames[nframes].size + 2; 271 272 /* Last frame */ 273 if (++nframes >= MAX_FRAMES_PER_PACKET || eof) 274 break; 275 } 276 277 /* Pack */ 278 *pkt_size = max_pkt_size; 279 280 return pjmedia_codec_amr_pack(frames, nframes, setting, pkt, pkt_size); 281 #endif 282 283 return PJ_ENOTSUP; 259 info->mode = setting->enc_mode; 260 261 frames[i].buf = sf->data; 262 frames[i].size = len; 263 } 264 265 output->size = output_buf_len; 266 267 return pjmedia_codec_amr_pack(frames, input->subframe_cnt, enc_setting, 268 output->buf, &output->size); 284 269 } 285 270 … … 302 287 return status; 303 288 289 // CMR is not supported for now. 304 290 /* Check Change Mode Request. */ 305 if ((setting->amr_nb && cmr <= 7) || (!setting->amr_nb && cmr <= 8)) {306 s->enc_mode = cmr;307 }291 //if ((setting->amr_nb && cmr <= 7) || (!setting->amr_nb && cmr <= 8)) { 292 // s->enc_mode = cmr; 293 //} 308 294 309 295 return PJ_SUCCESS; … … 800 786 pjmedia_frame_ext *output_ = (pjmedia_frame_ext*) output; 801 787 802 pj_assert(input && input->size > 0);788 pj_assert(input); 803 789 804 790 #if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR … … 807 793 * into encoder bits order. 808 794 */ 809 if (desc->pt == PJMEDIA_RTP_PT_AMR ) {810 pjmedia_frame frame;795 if (desc->pt == PJMEDIA_RTP_PT_AMR || desc->pt == PJMEDIA_RTP_PT_AMRWB) { 796 pjmedia_frame input_; 811 797 pjmedia_codec_amr_pack_setting *setting; 812 798 813 799 setting = &((amr_settings_t*)codec_data->codec_setting)->dec_setting; 814 800 815 frame = *input; 816 pjmedia_codec_amr_predecode(input, setting, &frame); 801 input_ = *input; 802 pjmedia_codec_amr_predecode(input, setting, &input_); 803 804 pjmedia_frame_ext_append_subframe(output_, input_.buf, 805 (pj_uint16_t)(input_.size << 3), 806 (pj_uint16_t)desc->samples_per_frame); 807 808 return PJ_SUCCESS; 817 809 } 818 810 #endif 819 /* 820 PJ_ASSERT_RETURN(output_buf_len >= sizeof(pjmedia_frame_ext) + 821 sizeof(pjmedia_frame_ext_subframe) + 822 input->size, 823 PJMEDIA_CODEC_EFRMTOOSHORT); 824 */ 825 811 826 812 pjmedia_frame_ext_append_subframe(output_, input->buf, 827 813 (pj_uint16_t)(input->size << 3), -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/conf_switch.c
r2438 r2444 68 68 struct conf_port 69 69 { 70 SLOT_TYPE slot; /**< Array of listeners. */ 70 71 pj_str_t name; /**< Port name. */ 71 72 pjmedia_port *port; /**< get_frame() and put_frame() */ … … 77 78 78 79 /* Shortcut for port info. */ 79 unsigned clock_rate; /**< Port's clock rate. */ 80 unsigned samples_per_frame; /**< Port's samples per frame. */ 81 unsigned channel_count; /**< Port's channel count. */ 80 pjmedia_port_info *info; 82 81 83 82 /* Calculated signal levels: */ … … 118 117 pj_mutex_t *mutex; /**< Conference mutex. */ 119 118 struct conf_port **ports; /**< Array of ports. */ 120 unsigned clock_rate; /**< Sampling rate. */121 unsigned channel_count;/**< Number of channels (1=mono). */122 unsigned samples_per_frame; /**< Samples per frame. */123 unsigned bits_per_sample; /**< Bits per sample. */124 119 pj_uint8_t buf[BUFFER_SIZE]; /**< Common buffer. */ 125 120 }; … … 146 141 pjmedia_frame *f; 147 142 143 PJ_ASSERT_RETURN(pool && conf && port && name && p_conf_port, PJ_EINVAL); 144 148 145 /* Create port. */ 149 146 conf_port = PJ_POOL_ZALLOC_T(pool, struct conf_port); … … 163 160 164 161 /* Save some port's infos, for convenience. */ 165 if (port) { 166 conf_port->port = port; 167 conf_port->clock_rate = port->info.clock_rate; 168 conf_port->samples_per_frame = port->info.samples_per_frame; 169 conf_port->channel_count = port->info.channel_count; 170 } else { 171 conf_port->port = NULL; 172 conf_port->clock_rate = conf->clock_rate; 173 conf_port->samples_per_frame = conf->samples_per_frame; 174 conf_port->channel_count = conf->channel_count; 175 } 162 conf_port->port = port; 163 conf_port->info = &port->info; 176 164 177 165 /* Init pjmedia_frame structure in the TX buffer. */ … … 196 184 197 185 198 status = create_conf_port(pool, conf, NULL, &name, &conf_port);186 status = create_conf_port(pool, conf, conf->master_port, &name, &conf_port); 199 187 if (status != PJ_SUCCESS) 200 188 return status; … … 206 194 pjmedia_snd_stream *strm; 207 195 pjmedia_snd_stream_info si; 196 pjmedia_port_info *master_port_info = (pjmedia_port_info*) 197 &conf->master_port->info; 208 198 209 199 /* … … 212 202 */ 213 203 if (conf->options & PJMEDIA_CONF_NO_MIC) { 214 status = pjmedia_snd_port_create_player(pool, -1, conf->clock_rate, 215 conf->channel_count, 216 conf->samples_per_frame, 217 conf->bits_per_sample, 218 0, /* options */ 219 &conf->snd_dev_port); 204 status = pjmedia_snd_port_create_player( 205 pool, -1, 206 master_port_info->clock_rate, 207 master_port_info->channel_count, 208 master_port_info->samples_per_frame, 209 master_port_info->bits_per_sample, 210 0, /* options */ 211 &conf->snd_dev_port); 220 212 221 213 } else { 222 status = pjmedia_snd_port_create( pool, -1, -1, conf->clock_rate, 223 conf->channel_count, 224 conf->samples_per_frame, 225 conf->bits_per_sample, 226 0, /* Options */ 227 &conf->snd_dev_port); 228 214 status = pjmedia_snd_port_create( 215 pool, -1, -1, 216 master_port_info->clock_rate, 217 master_port_info->channel_count, 218 master_port_info->samples_per_frame, 219 master_port_info->bits_per_sample, 220 0, /* Options */ 221 &conf->snd_dev_port); 229 222 } 230 223 … … 246 239 247 240 /* Add the port to the bridge */ 241 conf_port->slot = 0; 248 242 conf->ports[0] = conf_port; 249 243 conf->port_cnt++; … … 286 280 conf->options = options; 287 281 conf->max_ports = max_ports; 288 conf->clock_rate = clock_rate;289 conf->channel_count = channel_count;290 conf->samples_per_frame = samples_per_frame;291 conf->bits_per_sample = bits_per_sample;292 293 282 294 283 /* Create and initialize the master port interface. */ … … 425 414 conf->ports[0]->name.slen = len; 426 415 427 if (conf->master_port) 428 conf->master_port->info.name = conf->ports[0]->name; 416 conf->master_port->info.name = conf->ports[0]->name; 429 417 430 418 return PJ_SUCCESS; … … 445 433 446 434 PJ_ASSERT_RETURN(conf && pool && strm_port, PJ_EINVAL); 435 /* 447 436 PJ_ASSERT_RETURN(conf->clock_rate == strm_port->info.clock_rate, 448 437 PJMEDIA_ENCCLOCKRATE); … … 451 440 PJ_ASSERT_RETURN(conf->bits_per_sample == strm_port->info.bits_per_sample, 452 441 PJMEDIA_ENCBITS); 442 */ 453 443 454 444 /* Port's samples per frame should be equal to or multiplication of 455 445 * conference's samples per frame. 456 446 */ 447 /* 448 Not sure if this is needed! 457 449 PJ_ASSERT_RETURN((conf->samples_per_frame % 458 450 strm_port->info.samples_per_frame==0) || … … 460 452 conf->samples_per_frame==0), 461 453 PJMEDIA_ENCSAMPLESPFRAME); 454 */ 462 455 463 456 /* If port_name is not specified, use the port's name */ … … 489 482 490 483 /* Put the port. */ 484 conf_port->slot = index; 491 485 conf->ports[index] = conf_port; 492 486 conf->port_cnt++; … … 589 583 dst_port = conf->ports[sink_slot]; 590 584 585 /* Source and sink ptime must be equal or a multiplication factor. */ 586 if ((src_port->info->samples_per_frame % 587 dst_port->info->samples_per_frame != 0) && 588 (dst_port->info->samples_per_frame % 589 src_port->info->samples_per_frame != 0)) 590 { 591 pj_mutex_unlock(conf->mutex); 592 return PJMEDIA_ENCSAMPLESPFRAME; 593 } 594 591 595 /* Check if source and sink has compatible format */ 592 596 if (src_slot != 0 && sink_slot != 0 && … … 678 682 --src_port->listener_cnt; 679 683 --dst_port->transmitter_cnt; 684 685 /* Clean up sink TX buffer. */ 686 pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext)); 680 687 681 688 PJ_LOG(4,(THIS_FILE, … … 777 784 pj_assert(conf->connect_cnt > 0); 778 785 --conf->connect_cnt; 786 787 /* Clean up TX buffer. */ 788 pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext)); 779 789 } 780 790 … … 842 852 info->listener_cnt = conf_port->listener_cnt; 843 853 info->listener_slots = conf_port->listener_slots; 844 info->clock_rate = conf_port->clock_rate; 845 info->channel_count = conf_port->channel_count; 846 info->samples_per_frame = conf_port->samples_per_frame; 847 info->bits_per_sample = conf->bits_per_sample; 848 info->format = slot? conf_port->port->info.format : 849 conf->master_port->info.format; 854 info->clock_rate = conf_port->info->clock_rate; 855 info->channel_count = conf_port->info->channel_count; 856 info->samples_per_frame = conf_port->info->samples_per_frame; 857 info->bits_per_sample = conf_port->info->bits_per_sample; 858 info->format = conf_port->port->info.format; 850 859 851 860 return PJ_SUCCESS; … … 991 1000 * samples per frame. 992 1001 */ 993 if (f_dst->samples_cnt == cport_dst-> samples_per_frame)1002 if (f_dst->samples_cnt == cport_dst->info->samples_per_frame) 994 1003 { 995 if (cport_dst-> port) {1004 if (cport_dst->slot) { 996 1005 pjmedia_port_put_frame(cport_dst->port, 997 1006 (pjmedia_frame*)f_dst); … … 1004 1013 /* Update TX timestamp. */ 1005 1014 pj_add_timestamp32(&cport_dst->ts_tx, 1006 cport_dst->samples_per_frame); 1007 1015 cport_dst->info->samples_per_frame); 1008 1016 } 1009 1017 } … … 1020 1028 /* Copy frame to listener's TX buffer. */ 1021 1029 nsamples_to_copy = f_end - f_start; 1022 nsamples_req = cport_dst->samples_per_frame - (frm_dst->size>>1); 1030 nsamples_req = cport_dst->info->samples_per_frame - 1031 (frm_dst->size>>1); 1023 1032 if (nsamples_to_copy > nsamples_req) 1024 1033 nsamples_to_copy = nsamples_req; 1034 1025 1035 pjmedia_copy_samples((pj_int16_t*)frm_dst->buf + (frm_dst->size>>1), 1026 1036 f_start, … … 1033 1043 * samples per frame. 1034 1044 */ 1035 if ((frm_dst->size >> 1) == cport_dst-> samples_per_frame)1045 if ((frm_dst->size >> 1) == cport_dst->info->samples_per_frame) 1036 1046 { 1037 if (cport_dst-> port) {1047 if (cport_dst->slot) { 1038 1048 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1039 1049 … … 1044 1054 /* Update TX timestamp. */ 1045 1055 pj_add_timestamp32(&cport_dst->ts_tx, 1046 cport_dst-> samples_per_frame);1056 cport_dst->info->samples_per_frame); 1047 1057 } 1048 1058 } … … 1059 1069 if (frm_dst->size != 0) { 1060 1070 pjmedia_zero_samples((pj_int16_t*)frm_dst->buf, 1061 cport_dst-> samples_per_frame -1071 cport_dst->info->samples_per_frame - 1062 1072 (frm_dst->size>>1)); 1063 1073 1064 1074 frm_dst->type = PJMEDIA_FRAME_TYPE_AUDIO; 1065 frm_dst->size = cport_dst-> samples_per_frame << 1;1066 if (cport_dst-> port) {1075 frm_dst->size = cport_dst->info->samples_per_frame << 1; 1076 if (cport_dst->slot) { 1067 1077 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1068 1078 … … 1073 1083 /* Update TX timestamp. */ 1074 1084 pj_add_timestamp32(&cport_dst->ts_tx, 1075 cport_dst-> samples_per_frame);1085 cport_dst->info->samples_per_frame); 1076 1086 } 1077 1087 } else { … … 1081 1091 frm_dst->type = PJMEDIA_FRAME_TYPE_EXTENDED; 1082 1092 pjmedia_frame_ext_append_subframe(f_dst, NULL, 0, (pj_uint16_t) 1083 (cport_dst->samples_per_frame- 1084 f_dst->samples_cnt)); 1085 if (cport_dst->port) { 1093 (cport_dst->info->samples_per_frame - f_dst->samples_cnt)); 1094 if (cport_dst->slot) { 1086 1095 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1087 1096 … … 1093 1102 /* Update TX timestamp. */ 1094 1103 pj_add_timestamp32(&cport_dst->ts_tx, 1095 cport_dst-> samples_per_frame);1104 cport_dst->info->samples_per_frame); 1096 1105 } 1097 1106 } … … 1103 1112 frm_dst->type = PJMEDIA_FRAME_TYPE_NONE; 1104 1113 frm_dst->timestamp = cport_dst->ts_tx; 1105 if (cport_dst-> port)1114 if (cport_dst->slot) 1106 1115 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1107 1116 1108 1117 /* Update TX timestamp. */ 1109 pj_add_timestamp32(&cport_dst->ts_tx, cport_dst-> samples_per_frame);1118 pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->info->samples_per_frame); 1110 1119 } 1111 1120 } … … 1144 1153 1145 1154 /* Update clock of the port. */ 1146 pj_add_timestamp32(&cport->ts_clock, conf->samples_per_frame); 1155 pj_add_timestamp32(&cport->ts_clock, 1156 conf->master_port->info.samples_per_frame); 1147 1157 1148 1158 /* Skip if we're not allowed to receive from this port or … … 1166 1176 pj_int32_t level; 1167 1177 1168 pj_add_timestamp32(&cport->ts_rx, cport-> samples_per_frame);1178 pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame); 1169 1179 1170 1180 f->buf = &conf->buf[sizeof(pjmedia_frame)]; … … 1200 1210 if (listener->tx_setting == PJMEDIA_PORT_DISABLE) { 1201 1211 pj_add_timestamp32(&listener->ts_tx, 1202 listener-> samples_per_frame);1212 listener->info->samples_per_frame); 1203 1213 listener->tx_level = 0; 1204 1214 continue; … … 1250 1260 1251 1261 pjmedia_port_put_frame(cport->port, &tmp_f); 1252 pj_add_timestamp32(&cport->ts_tx, cport-> samples_per_frame);1262 pj_add_timestamp32(&cport->ts_tx, cport->info->samples_per_frame); 1253 1263 } 1254 1264 } … … 1269 1279 pj_uint16_t samples_per_subframe; 1270 1280 1271 if (f_src_->samples_cnt < this_cport-> samples_per_frame) {1281 if (f_src_->samples_cnt < this_cport->info->samples_per_frame) { 1272 1282 pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 1273 1283 frame->type = PJMEDIA_FRAME_TYPE_NONE; … … 1281 1291 1282 1292 1283 while (f_dst->samples_cnt < this_cport-> samples_per_frame) {1293 while (f_dst->samples_cnt < this_cport->info->samples_per_frame) { 1284 1294 sf = pjmedia_frame_ext_get_subframe(f_src_, i++); 1285 1295 pj_assert(sf); … … 1292 1302 1293 1303 } else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) { 1294 if ((f_src->size>>1) < this_cport-> samples_per_frame) {1304 if ((f_src->size>>1) < this_cport->info->samples_per_frame) { 1295 1305 pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 1296 1306 frame->type = PJMEDIA_FRAME_TYPE_NONE; … … 1300 1310 pjmedia_copy_samples((pj_int16_t*)frame->buf, 1301 1311 (pj_int16_t*)f_src->buf, 1302 this_cport-> samples_per_frame);1303 frame->size = this_cport-> samples_per_frame << 1;1312 this_cport->info->samples_per_frame); 1313 frame->size = this_cport->info->samples_per_frame << 1; 1304 1314 1305 1315 /* Shift left TX buffer. */ … … 1308 1318 pjmedia_move_samples((pj_int16_t*)f_src->buf, 1309 1319 (pj_int16_t*)f_src->buf + 1310 this_cport-> samples_per_frame,1320 this_cport->info->samples_per_frame, 1311 1321 f_src->size >> 1); 1312 1322 } else { /* PJMEDIA_FRAME_TYPE_NONE */ … … 1334 1344 pj_int32_t level; 1335 1345 1336 pj_add_timestamp32(&cport->ts_rx, cport-> samples_per_frame);1346 pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame); 1337 1347 1338 1348 /* Skip if this port is muted/disabled. */ … … 1373 1383 if (listener->tx_setting == PJMEDIA_PORT_DISABLE) { 1374 1384 pj_add_timestamp32(&listener->ts_tx, 1375 listener-> samples_per_frame);1385 listener->info->samples_per_frame); 1376 1386 listener->tx_level = 0; 1377 1387 continue; … … 1381 1391 if (listener == cport) { 1382 1392 pj_add_timestamp32(&listener->ts_tx, 1383 listener-> samples_per_frame);1393 listener->info->samples_per_frame); 1384 1394 listener->tx_level = 0; 1385 1395 continue; -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound_aps.cpp
r2439 r2444 99 99 pj_int16_t *rec_buf; 100 100 pj_uint16_t rec_buf_len; 101 void *strm_data; 101 102 }; 102 103 … … 696 697 } 697 698 699 /* Pack/unpack G.729 frame of S60 DSP codec, taken from: 700 * http://wiki.forum.nokia.com/index.php/TSS000776_-_Payload_conversion_for_G.729_audio_format 701 */ 702 #include "s60_g729_bitstream.h" 703 #include <pjmedia-codec/amr_helper.h> 704 698 705 static void RecCb(TAPSCommBuffer &buf, void *user_data) 699 706 { 700 707 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 701 708 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->rec_buf; 702 unsigned samples_processed = 0; 703 709 704 710 switch(strm->setting.format.u32) { 705 706 case PJMEDIA_FOURCC_G711U: 707 case PJMEDIA_FOURCC_G711A: 708 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 709 710 /* Detect the recorder G.711 frame size, player frame size will follow 711 * this recorder frame size. 712 */ 713 if (aps_g711_frame_len == 0) { 714 aps_g711_frame_len = buf.iBuffer.Length() < 160? 80 : 160; 715 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 716 aps_g711_frame_len)); 717 } 718 719 /* Convert APS buffer format into pjmedia_frame_ext. Whenever 720 * samples count in the frame is equal to stream's samples per frame, 721 * call parent stream callback. 722 */ 723 while (samples_processed < aps_g711_frame_len) { 724 unsigned tmp; 725 const pj_uint8_t *pb = (const pj_uint8_t*)buf.iBuffer.Ptr() + 2 + 726 samples_processed; 727 728 tmp = PJ_MIN(strm->samples_per_frame - frame->samples_cnt, 729 aps_g711_frame_len - samples_processed); 711 case PJMEDIA_FOURCC_AMR: 712 { 713 const pj_uint8_t *p = (const pj_uint8_t*)buf.iBuffer.Ptr() + 1; 714 unsigned len = buf.iBuffer.Length() - 1; 730 715 731 pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp); 732 samples_processed += tmp; 733 716 pjmedia_frame_ext_append_subframe(frame, p, len << 3, 160); 734 717 if (frame->samples_cnt == strm->samples_per_frame) { 735 718 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; … … 741 724 break; 742 725 726 case PJMEDIA_FOURCC_G729: 727 { 728 /* Check if we got a normal or SID frame. */ 729 if (buf.iBuffer[0] != 0 || buf.iBuffer[1] != 0) { 730 enum { NORMAL_LEN = 22, SID_LEN = 8 }; 731 TBitStream *bitstream = (TBitStream*)strm->strm_data; 732 unsigned src_len = buf.iBuffer.Length()- 2; 733 734 pj_assert(src_len == NORMAL_LEN || src_len == SID_LEN); 735 736 const TDesC8& p = bitstream->CompressG729Frame( 737 buf.iBuffer.Right(src_len), 738 src_len == SID_LEN); 739 740 pjmedia_frame_ext_append_subframe(frame, p.Ptr(), 741 p.Length() << 3, 80); 742 } else { /* We got null frame. */ 743 pjmedia_frame_ext_append_subframe(frame, NULL, 0, 80); 744 } 745 746 if (frame->samples_cnt == strm->samples_per_frame) { 747 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 748 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 749 frame->samples_cnt = 0; 750 frame->subframe_cnt = 0; 751 } 752 } 753 break; 754 755 case PJMEDIA_FOURCC_ILBC: 756 { 757 unsigned samples_got; 758 759 samples_got = strm->setting.mode == 30? 240 : 160; 760 761 /* Check if we got a normal frame. */ 762 if (buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0) { 763 const pj_uint8_t *p = (const pj_uint8_t*)buf.iBuffer.Ptr() + 2; 764 unsigned len = buf.iBuffer.Length() - 2; 765 766 pjmedia_frame_ext_append_subframe(frame, p, len << 3, 767 samples_got); 768 } else { /* We got null frame. */ 769 pjmedia_frame_ext_append_subframe(frame, NULL, 0, samples_got); 770 } 771 772 if (frame->samples_cnt == strm->samples_per_frame) { 773 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 774 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 775 frame->samples_cnt = 0; 776 frame->subframe_cnt = 0; 777 } 778 } 779 break; 780 781 case PJMEDIA_FOURCC_G711U: 782 case PJMEDIA_FOURCC_G711A: 783 { 784 unsigned samples_processed = 0; 785 786 /* Make sure it is normal frame. */ 787 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 788 789 /* Detect the recorder G.711 frame size, player frame size will 790 * follow this recorder frame size. 791 */ 792 if (aps_g711_frame_len == 0) { 793 aps_g711_frame_len = buf.iBuffer.Length() < 160? 80 : 160; 794 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 795 aps_g711_frame_len)); 796 } 797 798 /* Convert APS buffer format into pjmedia_frame_ext. Whenever 799 * samples count in the frame is equal to stream's samples per 800 * frame, call parent stream callback. 801 */ 802 while (samples_processed < aps_g711_frame_len) { 803 unsigned tmp; 804 const pj_uint8_t *pb = (const pj_uint8_t*)buf.iBuffer.Ptr() + 805 2 + samples_processed; 806 807 tmp = PJ_MIN(strm->samples_per_frame - frame->samples_cnt, 808 aps_g711_frame_len - samples_processed); 809 810 pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp); 811 samples_processed += tmp; 812 813 if (frame->samples_cnt == strm->samples_per_frame) { 814 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 815 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 816 frame->samples_cnt = 0; 817 frame->subframe_cnt = 0; 818 } 819 } 820 } 821 break; 822 743 823 default: 744 824 break; … … 750 830 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 751 831 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->play_buf; 752 unsigned g711_frame_len = aps_g711_frame_len;753 unsigned samples_ready = 0;754 832 755 833 /* Init buffer attributes and header. */ … … 759 837 760 838 switch(strm->setting.format.u32) { 839 case PJMEDIA_FOURCC_AMR: 840 { 841 if (frame->samples_cnt == 0) { 842 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 843 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 844 845 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || 846 frame->base.type==PJMEDIA_FRAME_TYPE_NONE); 847 } 848 849 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 850 pjmedia_frame_ext_subframe *sf; 851 unsigned samples_cnt; 852 853 sf = pjmedia_frame_ext_get_subframe(frame, 0); 854 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 855 856 if (sf->data && sf->bitlen) { 857 /* AMR header for APS is one byte, the format (may be!): 858 * 0xxxxy00, where xxxx:frame type, y:not sure. 859 */ 860 unsigned len = sf->bitlen>>3; 861 enum {SID_FT = 8 }; 862 pj_uint8_t amr_header = 4, ft = SID_FT; 863 864 if (sf->bitlen & 0x07) 865 ++len; 866 867 if (len >= pjmedia_codec_amrnb_framelen[0]) 868 ft = pjmedia_codec_amr_get_mode2(PJ_TRUE, len); 869 870 amr_header |= ft << 3; 871 buf.iBuffer.Append(amr_header); 872 873 buf.iBuffer.Append((TUint8*)sf->data, len); 874 } else { 875 buf.iBuffer.Append(0); 876 } 877 878 pjmedia_frame_ext_pop_subframes(frame, 1); 879 880 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 881 buf.iBuffer.Append(0); 882 883 frame->samples_cnt = 0; 884 frame->subframe_cnt = 0; 885 } 886 } 887 break; 888 889 case PJMEDIA_FOURCC_G729: 890 { 891 if (frame->samples_cnt == 0) { 892 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 893 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 894 895 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || 896 frame->base.type==PJMEDIA_FRAME_TYPE_NONE); 897 } 898 899 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 900 pjmedia_frame_ext_subframe *sf; 901 unsigned samples_cnt; 902 903 sf = pjmedia_frame_ext_get_subframe(frame, 0); 904 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 905 906 if (sf->data && sf->bitlen) { 907 enum { NORMAL_LEN = 10, SID_LEN = 2 }; 908 pj_bool_t sid_frame = ((sf->bitlen >> 3) == SID_LEN); 909 TBitStream *bitstream = (TBitStream*)strm->strm_data; 910 const TPtrC8 src(sf->data, sf->bitlen>>3); 911 const TDesC8 &dst = bitstream->ExpandG729Frame(src, 912 sid_frame); 913 if (sid_frame) { 914 buf.iBuffer.Append(0); 915 buf.iBuffer.Append(1); 916 } else { 917 buf.iBuffer.Append(1); 918 buf.iBuffer.Append(0); 919 } 920 buf.iBuffer.Append(dst); 921 } else { 922 buf.iBuffer.Append(0); 923 buf.iBuffer.Append(0); 924 } 925 926 pjmedia_frame_ext_pop_subframes(frame, 1); 927 928 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 929 buf.iBuffer.Append(0); 930 buf.iBuffer.Append(0); 931 932 frame->samples_cnt = 0; 933 frame->subframe_cnt = 0; 934 } 935 } 936 break; 937 938 case PJMEDIA_FOURCC_ILBC: 939 { 940 if (frame->samples_cnt == 0) { 941 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 942 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 943 944 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || 945 frame->base.type==PJMEDIA_FRAME_TYPE_NONE); 946 } 947 948 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 949 pjmedia_frame_ext_subframe *sf; 950 unsigned samples_cnt; 951 952 sf = pjmedia_frame_ext_get_subframe(frame, 0); 953 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 954 pj_assert((strm->setting.mode == 30 && samples_cnt == 240) || 955 (strm->setting.mode == 20 && samples_cnt == 160)); 956 957 if (sf->data && sf->bitlen) { 958 buf.iBuffer.Append(1); 959 buf.iBuffer.Append(0); 960 buf.iBuffer.Append((TUint8*)sf->data, sf->bitlen>>3); 961 } else { 962 buf.iBuffer.Append(0); 963 buf.iBuffer.Append(0); 964 } 965 966 pjmedia_frame_ext_pop_subframes(frame, 1); 967 968 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 969 buf.iBuffer.Append(0); 970 buf.iBuffer.Append(0); 971 972 frame->samples_cnt = 0; 973 frame->subframe_cnt = 0; 974 } 975 } 976 break; 977 761 978 case PJMEDIA_FOURCC_G711U: 762 979 case PJMEDIA_FOURCC_G711A: 763 980 { 764 /* Add header. */ 765 buf.iBuffer.Append(1); 766 buf.iBuffer.Append(0); 767 981 unsigned samples_ready = 0; 982 unsigned samples_req = aps_g711_frame_len; 983 768 984 /* Assume frame size is 10ms if frame size hasn't been known. */ 769 if ( g711_frame_len== 0)770 g711_frame_len= 80;985 if (samples_req == 0) 986 samples_req = 80; 771 987 772 988 /* Call parent stream callback to get samples to play. */ 773 while (samples_ready < g711_frame_len) {989 while (samples_ready < samples_req) { 774 990 if (frame->samples_cnt == 0) { 775 991 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 776 strm->play_cb(strm->user_data, 0, strm->play_buf, 777 strm->samples_per_frame<<1); 992 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 778 993 779 994 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || … … 787 1002 sf = pjmedia_frame_ext_get_subframe(frame, 0); 788 1003 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 789 if (sf->data && sf->bitlen) 1004 if (sf->data && sf->bitlen) { 1005 buf.iBuffer.Append(1); 1006 buf.iBuffer.Append(0); 790 1007 buf.iBuffer.Append((TUint8*)sf->data, sf->bitlen>>3); 791 else { 792 pj_uint8_t silence_code; 793 794 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U) 795 silence_code = pjmedia_linear2ulaw(0); 796 else 797 silence_code = pjmedia_linear2alaw(0); 798 799 buf.iBuffer.AppendFill(silence_code, samples_cnt); 1008 } else { 1009 buf.iBuffer.Append(0); 1010 buf.iBuffer.Append(0); 800 1011 } 801 1012 samples_ready += samples_cnt; … … 804 1015 805 1016 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 806 pj_uint8_t silence_code; 807 808 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U) 809 silence_code = pjmedia_linear2ulaw(0); 810 else 811 silence_code = pjmedia_linear2alaw(0); 812 813 buf.iBuffer.AppendFill(silence_code, 814 g711_frame_len - samples_ready); 815 samples_ready = g711_frame_len; 1017 buf.iBuffer.Append(0); 1018 buf.iBuffer.Append(0); 1019 1020 samples_ready = samples_req; 816 1021 frame->samples_cnt = 0; 817 1022 frame->subframe_cnt = 0; … … 922 1127 } 923 1128 924 aps_setting.vad = strm->setting.format.u32==PJMEDIA_FOURCC_L16? 925 EFalse : strm->setting.vad; 1129 /* Disable VAD on L16 and G711. */ 1130 if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || 1131 strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || 1132 strm->setting.format.u32 == PJMEDIA_FOURCC_G711A) 1133 { 1134 aps_setting.vad = EFalse; 1135 } else { 1136 aps_setting.vad = strm->setting.vad; 1137 } 1138 926 1139 aps_setting.plc = strm->setting.plc; 927 1140 aps_setting.cng = strm->setting.cng; … … 958 1171 strm->rec_buf_len = 0; 959 1172 1173 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G729) { 1174 TBitStream *g729_bitstream = new TBitStream; 1175 1176 PJ_ASSERT_RETURN(g729_bitstream, PJ_ENOMEM); 1177 strm->strm_data = (void*)g729_bitstream; 1178 } 1179 960 1180 // Done. 961 1181 *p_snd_strm = strm; … … 984 1204 pj_bzero(&setting, sizeof(setting)); 985 1205 setting.format.u32 = PJMEDIA_FOURCC_L16; 986 setting.bitrate = 128000;987 1206 988 1207 return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, … … 1007 1226 pj_bzero(&setting, sizeof(setting)); 1008 1227 setting.format.u32 = PJMEDIA_FOURCC_L16; 1009 setting.bitrate = 128000;1010 1228 1011 1229 return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, … … 1033 1251 pj_bzero(&setting, sizeof(setting)); 1034 1252 setting.format.u32 = PJMEDIA_FOURCC_L16; 1035 setting.bitrate = 128000;1036 1253 1037 1254 return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, … … 1121 1338 stream->engine = NULL; 1122 1339 1340 if (stream->setting.format.u32 == PJMEDIA_FOURCC_G729) { 1341 TBitStream *g729_bitstream = (TBitStream*)stream->strm_data; 1342 stream->strm_data = NULL; 1343 delete g729_bitstream; 1344 } 1345 1123 1346 pool = stream->pool; 1124 1347 if (pool) { -
pjproject/branches/projects/aps-direct/pjsip-apps/src/symbian_ua/ua.cpp
r2439 r2444 281 281 return; 282 282 283 /* Init sound device setting based on stream info. */ 283 284 pj_bzero(&setting, sizeof(setting)); 284 285 setting.format = strm_info->param->info.format; … … 287 288 setting.vad = strm_info->param->setting.vad; 288 289 setting.plc = strm_info->param->setting.plc; 290 if (setting.format.u32 == PJMEDIA_FOURCC_ILBC) { 291 unsigned i; 292 pjmedia_codec_fmtp *fmtp = &strm_info->param->setting.dec_fmtp; 293 294 /* Initialize mode. */ 295 setting.mode = 30; 296 297 /* Get mode. */ 298 for (i = 0; i < fmtp->cnt; ++i) { 299 if (pj_stricmp2(&fmtp->param[i].name, "mode") == 0) { 300 setting.mode = (pj_uint32_t) pj_strtoul(&fmtp->param[i].val); 301 break; 302 } 303 } 304 } 305 306 samples_per_frame = strm_info->param->info.clock_rate * 307 strm_info->param->info.frm_ptime * 308 strm_info->param->info.channel_cnt / 309 1000; 310 311 /* Close sound device. */ 312 conf = pjsua_set_no_snd_dev(); 313 314 /* Reset conference attributes. */ 315 conf->info.samples_per_frame = samples_per_frame; 316 conf->info.clock_rate = 8000; 317 conf->info.channel_count = 1; 318 conf->info.bits_per_sample = 16; 289 319 290 320 /* Reopen sound device. */ 291 conf = pjsua_set_no_snd_dev();292 293 samples_per_frame = conf->info.samples_per_frame;294 295 321 status = pjmedia_snd_port_create2(app_pool, 296 322 PJMEDIA_DIR_CAPTURE_PLAYBACK,
Note: See TracChangeset
for help on using the changeset viewer.