- Timestamp:
- Jun 5, 2008 10:50:40 AM (16 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/codec.h
r974 r1983 376 376 /** 377 377 * Instruct the codec to encode the specified input frame. The input 378 * PCM samples MUST have ptime that is exactly equal tobase frame378 * PCM samples MUST have ptime that is multiplication of base frame 379 379 * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param). 380 380 * -
pjproject/trunk/pjmedia/include/pjmedia/jbuf.h
r1961 r1983 220 220 * buffer. 221 221 * @param size The frame size. 222 * @param bit_info Bit precise info of the frame, e.g: a frame may not 223 * exactly start and end at the octet boundary, so this 224 * field may be used for specifying start & end bit offset. 222 225 * @param frame_seq The frame sequence number. 223 226 * @param discarded Flag whether the frame is discarded by jitter buffer. … … 226 229 const void *frame, 227 230 pj_size_t size, 231 pj_uint32_t bit_info, 228 232 int frame_seq, 229 233 pj_bool_t *discarded); … … 268 272 * @param p_frm_type Pointer to receive frame type. 269 273 * @see pjmedia_jbuf_get_frame(). 274 * @param bit_info Bit precise info of the frame, e.g: a frame may not 275 * exactly start and end at the octet boundary, so this 276 * field may be used for specifying start & end bit offset. 270 277 */ 271 278 PJ_DECL(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb, 272 279 void *frame, 273 280 pj_size_t *size, 274 char *p_frm_type); 281 char *p_frm_type, 282 pj_uint32_t *bit_info); 275 283 276 284 -
pjproject/trunk/pjmedia/include/pjmedia/port.h
r974 r1983 299 299 struct pjmedia_frame 300 300 { 301 pjmedia_frame_type type; /**< Frame type. */ 302 void *buf; /**< Pointer to buffer. */ 303 pj_size_t size; /**< Frame size in bytes. */ 304 pj_timestamp timestamp; /**< Frame timestamp. */ 301 pjmedia_frame_type type; /**< Frame type. */ 302 void *buf; /**< Pointer to buffer. */ 303 pj_size_t size; /**< Frame size in bytes. */ 304 pj_timestamp timestamp; /**< Frame timestamp. */ 305 pj_uint32_t bit_info; /**< Bit info of the frame, sample case: 306 a frame may not exactly start and end 307 at the octet boundary, so this field 308 may be used for specifying start & 309 end bit offset. */ 305 310 }; 306 311 -
pjproject/trunk/pjmedia/src/pjmedia-codec/g722.c
r1977 r1983 533 533 pj_status_t status; 534 534 535 pj_assert(g722_data != NULL); 536 PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 537 538 if (output_buf_len < FRAME_LEN) 539 return PJMEDIA_CODEC_EFRMTOOSHORT; 540 541 PJ_ASSERT_RETURN(input->size/2 == SAMPLES_PER_FRAME, 542 PJMEDIA_CODEC_EPCMFRMINLEN); 535 pj_assert(g722_data && input && output); 536 537 PJ_ASSERT_RETURN((input->size >> 2) <= output_buf_len, 538 PJMEDIA_CODEC_EFRMTOOSHORT); 543 539 544 540 /* Detect silence */ … … 571 567 output->size = output_buf_len; 572 568 status = g722_enc_encode(&g722_data->encoder, (pj_int16_t*)input->buf, 573 SAMPLES_PER_FRAME, output->buf, &output->size);569 (input->size >> 1), output->buf, &output->size); 574 570 if (status != PJ_SUCCESS) { 575 571 output->size = 0; -
pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c
r1846 r1983 516 516 { 517 517 struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data; 518 519 pj_assert(gsm_data != NULL); 520 PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 521 522 if (output_buf_len < 33) 523 return PJMEDIA_CODEC_EFRMTOOSHORT; 524 525 PJ_ASSERT_RETURN(input->size==320, PJMEDIA_CODEC_EPCMFRMINLEN); 518 pj_int16_t *pcm_in; 519 unsigned in_size; 520 521 pj_assert(gsm_data && input && output); 522 523 pcm_in = (pj_int16_t*)input->buf; 524 in_size = input->size; 525 526 PJ_ASSERT_RETURN(in_size % 320 == 0, PJMEDIA_CODEC_EPCMFRMINLEN); 527 PJ_ASSERT_RETURN(output_buf_len >= 33 * in_size/320, 528 PJMEDIA_CODEC_EFRMTOOSHORT); 526 529 527 530 /* Detect silence */ … … 552 555 553 556 /* Encode */ 554 gsm_encode(gsm_data->encoder, (short*)input->buf, 555 (unsigned char*)output->buf); 556 557 output->size = 33; 557 output->size = 0; 558 while (in_size >= 320) { 559 gsm_encode(gsm_data->encoder, pcm_in, 560 (unsigned char*)output->buf + output->size); 561 pcm_in += 160; 562 output->size += 33; 563 in_size -= 320; 564 } 565 558 566 output->type = PJMEDIA_FRAME_TYPE_AUDIO; 559 567 -
pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c
r1266 r1983 511 511 { 512 512 struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec; 513 unsigned i; 514 515 pj_assert(ilbc_codec != NULL); 516 PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 517 518 if (output_buf_len < ilbc_codec->enc_frame_size) 519 return PJMEDIA_CODEC_EFRMTOOSHORT; 520 521 if (input->size != (ilbc_codec->enc_samples_per_frame << 1)) 522 return PJMEDIA_CODEC_EPCMFRMINLEN; 513 pj_int16_t *pcm_in; 514 unsigned nsamples; 515 516 pj_assert(ilbc_codec && input && output); 517 518 pcm_in = (pj_int16_t*)input->buf; 519 nsamples = input->size >> 1; 520 521 PJ_ASSERT_RETURN(nsamples % ilbc_codec->enc_samples_per_frame == 0, 522 PJMEDIA_CODEC_EPCMFRMINLEN); 523 PJ_ASSERT_RETURN(output_buf_len >= ilbc_codec->enc_frame_size * nsamples / 524 ilbc_codec->enc_samples_per_frame, 525 PJMEDIA_CODEC_EFRMTOOSHORT); 523 526 524 527 /* Detect silence */ … … 548 551 } 549 552 550 /* Convert to float */551 for (i=0; i<ilbc_codec->enc_samples_per_frame; ++i) {552 ilbc_codec->enc_block[i] = (float) (((pj_int16_t*)input->buf)[i]);553 }554 555 553 /* Encode */ 556 iLBC_encode((unsigned char *)output->buf, 557 ilbc_codec->enc_block, 558 &ilbc_codec->enc); 554 output->size = 0; 555 while (nsamples >= ilbc_codec->enc_samples_per_frame) { 556 unsigned i; 557 558 /* Convert to float */ 559 for (i=0; i<ilbc_codec->enc_samples_per_frame; ++i) { 560 ilbc_codec->enc_block[i] = (float) (*pcm_in++); 561 } 562 563 iLBC_encode((unsigned char *)output->buf + output->size, 564 ilbc_codec->enc_block, 565 &ilbc_codec->enc); 566 567 output->size += ilbc_codec->enc.no_of_bytes; 568 nsamples -= ilbc_codec->enc_samples_per_frame; 569 } 559 570 560 571 output->type = PJMEDIA_FRAME_TYPE_AUDIO; 561 output->size = ilbc_codec->enc.no_of_bytes;562 572 output->timestamp = input->timestamp; 563 573 -
pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c
r1266 r1983 565 565 while (samp!=samp_end) 566 566 *samp_out++ = pj_htons(*samp++); 567 #else 568 pjmedia_copy_samples(samp_out, samp, input->size >> 1); 567 569 #endif 568 570 … … 597 599 while (samp!=samp_end) 598 600 *samp_out++ = pj_htons(*samp++); 601 #else 602 pjmedia_copy_samples(samp_out, samp, input->size >> 1); 599 603 #endif 600 604 -
pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c
r1965 r1983 161 161 return PJMEDIA_CODEC_EFAILED; 162 162 163 /* Set thequality */164 if (p->quality != -1)165 speex_encoder_ctl(state, SPEEX_SET_QUALITY, &p->quality);163 /* We have to get maximum bitrate, so let's set maximum quality */ 164 tmp = 10; 165 speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp); 166 166 167 167 /* Sampling rate. */ … … 596 596 id = spx->param_id; 597 597 598 /* Only supports one frame per packet */599 PJ_ASSERT_RETURN(attr->setting.frm_per_pkt==1, PJ_EINVAL);600 601 598 /* 602 599 * Create and initialize encoder. … … 688 685 spx = (struct spx_private*) codec->codec_data; 689 686 690 /* Only supports one frame per packet */691 PJ_ASSERT_RETURN(attr->setting.frm_per_pkt==1, PJ_EINVAL);692 693 687 /* VAD */ 694 688 tmp = (attr->setting.vad != 0); … … 701 695 702 696 return PJ_SUCCESS; 697 } 698 699 #if 0 700 # define TRACE__(args) PJ_LOG(5,args) 701 #else 702 # define TRACE__(args) 703 #endif 704 705 #undef THIS_FUNC 706 #define THIS_FUNC "speex_get_next_frame" 707 708 #define NB_SUBMODES 16 709 #define NB_SUBMODE_BITS 4 710 711 #define SB_SUBMODES 8 712 #define SB_SUBMODE_BITS 3 713 714 /* This function will iterate frames & submodes in the Speex bits. 715 * Returns 0 if a frame found, otherwise returns -1. 716 */ 717 int speex_get_next_frame(SpeexBits *bits) 718 { 719 static const int inband_skip_table[NB_SUBMODES] = 720 {1, 1, 4, 4, 4, 4, 4, 4, 8, 8, 16, 16, 32, 32, 64, 64 }; 721 static const int wb_skip_table[SB_SUBMODES] = 722 {SB_SUBMODE_BITS+1, 36, 112, 192, 352, -1, -1, -1}; 723 724 unsigned submode; 725 unsigned nb_count = 0; 726 727 while (speex_bits_remaining(bits) >= 5) { 728 unsigned wb_count = 0; 729 unsigned bit_ptr = bits->bitPtr; 730 unsigned char_ptr = bits->charPtr; 731 732 /* WB frame */ 733 while ((speex_bits_remaining(bits) >= 4) 734 && speex_bits_unpack_unsigned(bits, 1)) 735 { 736 int advance; 737 738 submode = speex_bits_unpack_unsigned(bits, 3); 739 advance = wb_skip_table[submode]; 740 if (advance < 0) { 741 TRACE__((THIS_FUNC, "Invalid mode encountered. " 742 "The stream is corrupted.")); 743 return -1; 744 } 745 TRACE__((THIS_FUNC, "WB layer skipped: %d bits", advance)); 746 advance -= (SB_SUBMODE_BITS+1); 747 speex_bits_advance(bits, advance); 748 749 bit_ptr = bits->bitPtr; 750 char_ptr = bits->charPtr; 751 752 /* Consecutive subband frames may not exceed 2 frames */ 753 if (++wb_count > 2) 754 return -1; 755 } 756 757 /* End of bits, return the frame */ 758 if (speex_bits_remaining(bits) < 4) { 759 TRACE__((THIS_FUNC, "End of stream")); 760 return 0; 761 } 762 763 /* Stop iteration, return the frame */ 764 if (nb_count > 0) { 765 bits->bitPtr = bit_ptr; 766 bits->charPtr = char_ptr; 767 return 0; 768 } 769 770 /* Get control bits */ 771 submode = speex_bits_unpack_unsigned(bits, 4); 772 TRACE__((THIS_FUNC, "Control bits: %d at %d", 773 submode, bits->charPtr*8+bits->bitPtr)); 774 775 if (submode == 15) { 776 TRACE__((THIS_FUNC, "Found submode: terminator")); 777 return 0; 778 } else if (submode == 14) { 779 /* in-band signal; next 4 bits contain signal id */ 780 submode = speex_bits_unpack_unsigned(bits, 4); 781 TRACE__((THIS_FUNC, "Found submode: in-band %d bits", 782 inband_skip_table[submode])); 783 speex_bits_advance(bits, inband_skip_table[submode]); 784 } else if (submode == 13) { 785 /* user in-band; next 5 bits contain msg len */ 786 submode = speex_bits_unpack_unsigned(bits, 5); 787 TRACE__((THIS_FUNC, "Found submode: user-band %d bytes", submode)); 788 speex_bits_advance(bits, submode * 8); 789 } else if (submode > 8) { 790 TRACE__((THIS_FUNC, "Unknown sub-mode %d", submode)); 791 return 0; 792 } else { 793 /* NB frame */ 794 unsigned int advance = submode; 795 speex_mode_query(&speex_nb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); 796 if (advance < 0) { 797 TRACE__((THIS_FUNC, "Invalid mode encountered. " 798 "The stream is corrupted.")); 799 return -1; 800 } 801 TRACE__((THIS_FUNC, "Submode %d: %d bits", submode, advance)); 802 advance -= (NB_SUBMODE_BITS+1); 803 speex_bits_advance(bits, advance); 804 805 ++nb_count; 806 } 807 } 808 809 return 0; 703 810 } 704 811 … … 714 821 pjmedia_frame frames[]) 715 822 { 716 struct spx_private *spx; 717 unsigned frame_size, samples_per_frame; 718 unsigned count; 719 720 spx = (struct spx_private*) codec->codec_data; 721 722 frame_size = spx_factory.speex_param[spx->param_id].framesize; 723 samples_per_frame = spx_factory.speex_param[spx->param_id].samples_per_frame; 724 725 /* Don't really know how to do this... */ 726 count = 0; 727 while (pkt_size >= frame_size && count < *frame_cnt) { 728 frames[count].buf = pkt; 729 frames[count].size = frame_size; 823 struct spx_private *spx = (struct spx_private*) codec->codec_data; 824 unsigned samples_per_frame; 825 unsigned count = 0; 826 int char_ptr = 0; 827 int bit_ptr = 0; 828 829 samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame; 830 831 /* Copy the data into the speex bit-stream */ 832 speex_bits_read_from(&spx->dec_bits, (char*)pkt, pkt_size); 833 834 while (speex_get_next_frame(&spx->dec_bits) == 0 && 835 spx->dec_bits.charPtr != char_ptr) 836 { 837 frames[count].buf = (char*)pkt + char_ptr; 838 /* Bit info contains start bit offset of the frame */ 839 frames[count].bit_info = bit_ptr; 730 840 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 731 841 frames[count].timestamp.u64 = ts->u64 + count * samples_per_frame; 732 733 pkt_size -= frame_size; 842 frames[count].size = spx->dec_bits.charPtr - char_ptr; 843 if (spx->dec_bits.bitPtr) 844 ++frames[count].size; 845 846 bit_ptr = spx->dec_bits.bitPtr; 847 char_ptr = spx->dec_bits.charPtr; 848 734 849 ++count; 735 pkt = ((char*)pkt) + frame_size;736 }737 738 /* Just in case speex has silence frame which size is less than normal739 * frame size...740 */741 if (pkt_size && count < *frame_cnt) {742 frames[count].buf = pkt;743 frames[count].size = pkt_size;744 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;745 frames[count].timestamp.u64 = ts->u64 + count * samples_per_frame;746 ++count;747 850 } 748 851 749 852 *frame_cnt = count; 750 return PJ_SUCCESS; 751 } 752 753 /* 754 * Encode frame. 853 854 return PJ_SUCCESS; 855 } 856 857 /* 858 * Encode frames. 755 859 */ 756 860 static pj_status_t spx_codec_encode( pjmedia_codec *codec, … … 760 864 { 761 865 struct spx_private *spx; 762 unsigned sz; 763 int tx; 866 unsigned samples_per_frame; 867 int tx = 0; 868 spx_int16_t *pcm_in = (spx_int16_t*)input->buf; 869 unsigned nsamples; 764 870 765 871 spx = (struct spx_private*) codec->codec_data; … … 773 879 } 774 880 881 nsamples = input->size >> 1; 882 samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame; 883 884 PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, 885 PJMEDIA_CODEC_EPCMFRMINLEN); 886 775 887 /* Flush all the bits in the struct so we can encode a new frame */ 776 888 speex_bits_reset(&spx->enc_bits); 777 889 778 /* Encode the frame */ 779 tx = speex_encode_int(spx->enc, (spx_int16_t*)input->buf, 780 &spx->enc_bits); 890 /* Encode the frames */ 891 while (nsamples >= samples_per_frame) { 892 tx += speex_encode_int(spx->enc, pcm_in, &spx->enc_bits); 893 pcm_in += samples_per_frame; 894 nsamples -= samples_per_frame; 895 } 781 896 782 897 /* Check if we need not to transmit the frame (DTX) */ … … 790 905 791 906 /* Check size. */ 792 sz = speex_bits_nbytes(&spx->enc_bits); 793 pj_assert(sz <= output_buf_len); 907 pj_assert(speex_bits_nbytes(&spx->enc_bits) <= (int)output_buf_len); 794 908 795 909 /* Copy the bits to an array of char that can be written */ … … 811 925 { 812 926 struct spx_private *spx; 927 unsigned samples_per_frame; 813 928 814 929 spx = (struct spx_private*) codec->codec_data; 815 816 PJ_ASSERT_RETURN(output_buf_len >= 320, PJMEDIA_CODEC_EPCMTOOSHORT); 930 samples_per_frame=spx_factory.speex_param[spx->param_id].samples_per_frame; 931 932 PJ_ASSERT_RETURN(output_buf_len >= samples_per_frame << 1, 933 PJMEDIA_CODEC_EPCMTOOSHORT); 817 934 818 935 if (input->type != PJMEDIA_FRAME_TYPE_AUDIO) { 819 pjmedia_zero_samples((pj_int16_t*)output->buf, 160);820 output->size = 320;936 pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame); 937 output->size = samples_per_frame << 1; 821 938 output->timestamp.u64 = input->timestamp.u64; 822 939 output->type = PJMEDIA_FRAME_TYPE_AUDIO; … … 826 943 /* Copy the data into the bit-stream struct */ 827 944 speex_bits_read_from(&spx->dec_bits, (char*)input->buf, input->size); 945 946 /* Set Speex dec_bits pointer to the start bit of the frame */ 947 speex_bits_advance(&spx->dec_bits, input->bit_info); 828 948 829 949 /* Decode the data */ … … 831 951 832 952 output->type = PJMEDIA_FRAME_TYPE_AUDIO; 833 output->size = 320;953 output->size = samples_per_frame << 1; 834 954 output->timestamp.u64 = input->timestamp.u64; 835 836 955 837 956 return PJ_SUCCESS; -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r1961 r1983 39 39 int *flist_frame_type; 40 40 pj_size_t *flist_content_len; 41 pj_uint32_t *flist_bit_info; 41 42 unsigned flist_frame_size; 42 43 unsigned flist_max_count; … … 109 110 framelist->flist_max_count); 110 111 112 framelist->flist_bit_info = (pj_uint32_t*) 113 pj_pool_zalloc(pool, sizeof(framelist->flist_bit_info[0]) * 114 framelist->flist_max_count); 115 111 116 framelist->flist_empty = 1; 112 117 … … 135 140 static pj_bool_t jb_framelist_get(jb_framelist_t *framelist, 136 141 void *frame, pj_size_t *size, 137 pjmedia_jb_frame_type *p_type) 142 pjmedia_jb_frame_type *p_type, 143 pj_uint32_t *bit_info) 138 144 { 139 145 if (!framelist->flist_empty) { … … 144 150 *p_type = (pjmedia_jb_frame_type) 145 151 framelist->flist_frame_type[framelist->flist_head]; 146 *size = framelist->flist_content_len[framelist->flist_head]; 152 if (size) 153 *size = framelist->flist_content_len[framelist->flist_head]; 154 if (bit_info) 155 *bit_info = framelist->flist_bit_info[framelist->flist_head]; 147 156 148 157 pj_bzero(framelist->flist_buffer + … … 222 231 unsigned index, 223 232 const void *frame, 224 unsigned frame_size) 233 unsigned frame_size, 234 pj_uint32_t bit_info) 225 235 { 226 236 unsigned where; … … 264 274 framelist->flist_frame_type[where] = PJMEDIA_JB_NORMAL_FRAME; 265 275 framelist->flist_content_len[where] = frame_size; 276 framelist->flist_bit_info[where] = bit_info; 266 277 267 278 return PJ_TRUE; … … 479 490 int frame_seq) 480 491 { 481 pjmedia_jbuf_put_frame2(jb, frame, frame_size, frame_seq, NULL);492 pjmedia_jbuf_put_frame2(jb, frame, frame_size, 0, frame_seq, NULL); 482 493 } 483 494 … … 485 496 const void *frame, 486 497 pj_size_t frame_size, 498 pj_uint32_t bit_info, 487 499 int frame_seq, 488 500 pj_bool_t *discarded) … … 509 521 if (seq_diff > 0) { 510 522 511 while (jb_framelist_put_at(&jb->jb_framelist, 512 frame_seq,frame,min_frame_size) == PJ_FALSE)523 while (jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame, 524 min_frame_size, bit_info) == PJ_FALSE) 513 525 { 514 526 jb_framelist_remove_head(&jb->jb_framelist, … … 526 538 pj_bool_t res; 527 539 res = jb_framelist_put_at(&jb->jb_framelist,frame_seq,frame, 528 min_frame_size );540 min_frame_size, bit_info); 529 541 if (discarded) 530 542 *discarded = !res; … … 539 551 char *p_frame_type) 540 552 { 541 pj_size_t size; 542 543 pjmedia_jbuf_get_frame2(jb, frame, &size, p_frame_type); 553 pjmedia_jbuf_get_frame2(jb, frame, NULL, p_frame_type, NULL); 544 554 } 545 555 … … 550 560 void *frame, 551 561 pj_size_t *size, 552 char *p_frame_type) 562 char *p_frame_type, 563 pj_uint32_t *bit_info) 553 564 { 554 565 pjmedia_jb_frame_type ftype; … … 582 593 583 594 /* Retrieve a frame from frame list */ 584 if (jb_framelist_get(&jb->jb_framelist,frame,size,&ftype) == PJ_FALSE) { 595 if (jb_framelist_get(&jb->jb_framelist,frame,size,&ftype,bit_info) == 596 PJ_FALSE) 597 { 585 598 /* Can't return frame because jitter buffer is empty! */ 586 599 pj_bzero(frame, jb->jb_frame_size); -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r1961 r1983 230 230 char frame_type; 231 231 pj_size_t frame_size; 232 pj_uint32_t bit_info; 232 233 233 234 /* Get frame from jitter buffer. */ 234 235 pjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size, 235 &frame_type );236 &frame_type, &bit_info); 236 237 237 238 if (frame_type == PJMEDIA_JB_MISSING_FRAME) { … … 365 366 frame_in.buf = channel->out_pkt; 366 367 frame_in.size = frame_size; 368 frame_in.bit_info = bit_info; 367 369 frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO; /* ignored */ 368 370 … … 678 680 frame->buf != NULL) 679 681 { 680 unsigned ts, codec_samples_per_frame; 681 682 /* Repeatedly call encode if there are multiple frames to be 683 * sent. 684 */ 685 codec_samples_per_frame = stream->codec_param.info.enc_ptime * 686 stream->codec_param.info.clock_rate / 687 1000; 688 if (codec_samples_per_frame == 0) { 689 codec_samples_per_frame = stream->codec_param.info.frm_ptime * 690 stream->codec_param.info.clock_rate / 691 1000; 692 } 693 694 for (ts=0; ts<ts_len; ts += codec_samples_per_frame) { 695 pjmedia_frame tmp_out_frame, tmp_in_frame; 696 unsigned bytes_per_sample, max_size; 697 698 /* Nb of bytes in PCM sample */ 699 bytes_per_sample = stream->codec_param.info.pcm_bits_per_sample/8; 700 701 /* Split original PCM input frame into base frame size */ 702 tmp_in_frame.timestamp.u64 = frame->timestamp.u64 + ts; 703 tmp_in_frame.buf = ((char*)frame->buf) + ts * bytes_per_sample; 704 tmp_in_frame.size = codec_samples_per_frame * bytes_per_sample; 705 tmp_in_frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 706 707 /* Set output frame position */ 708 tmp_out_frame.buf = ((char*)frame_out.buf) + frame_out.size; 709 710 max_size = channel->out_pkt_size - sizeof(pjmedia_rtp_hdr) - 711 frame_out.size; 712 713 /* Encode! */ 714 status = stream->codec->op->encode( stream->codec, &tmp_in_frame, 715 max_size, &tmp_out_frame); 716 if (status != PJ_SUCCESS) { 717 LOGERR_((stream->port.info.name.ptr, 718 "Codec encode() error", status)); 719 return status; 720 } 721 722 /* tmp_out_frame.size may be zero for silence frame. */ 723 frame_out.size += tmp_out_frame.size; 724 725 /* Stop processing next PCM frame when encode() returns either 726 * CNG frame or NULL frame. 727 */ 728 if (tmp_out_frame.type!=PJMEDIA_FRAME_TYPE_AUDIO || 729 tmp_out_frame.size==0) 730 { 731 break; 732 } 733 682 /* Encode! */ 683 status = stream->codec->op->encode( stream->codec, frame, 684 channel->out_pkt_size - 685 sizeof(pjmedia_rtp_hdr), 686 &frame_out); 687 if (status != PJ_SUCCESS) { 688 LOGERR_((stream->port.info.name.ptr, 689 "Codec encode() error", status)); 690 return status; 734 691 } 735 692 … … 1218 1175 ext_seq = (unsigned)(frames[i].timestamp.u64 / ts_span); 1219 1176 pjmedia_jbuf_put_frame2(stream->jb, frames[i].buf, frames[i].size, 1220 ext_seq, &discarded);1177 frames[i].bit_info, ext_seq, &discarded); 1221 1178 if (discarded) 1222 1179 pkt_discarded = PJ_TRUE;
Note: See TracChangeset
for help on using the changeset viewer.