Changeset 2219 for pjproject/trunk
- Timestamp:
- Aug 16, 2008 6:46:08 AM (16 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia-codec/config.h
r2216 r2219 100 100 #endif 101 101 102 #ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB 103 # define PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB 1 104 #endif 105 102 106 #ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G729 103 107 # define PJMEDIA_HAS_INTEL_IPP_CODEC_G729 1 -
pjproject/trunk/pjmedia/src/pjmedia-codec/ipp_codecs.c
r2218 r2219 142 142 /* CUSTOM CALLBACKS */ 143 143 144 /* Get frame attributes: frame_type and bitrate. 144 /* This callback is useful for translating RTP frame into USC frame, e.g: 145 * reassigning frame attributes, reorder bitstream. Default behaviour of 146 * the translation is just setting the USC frame buffer & its size as 147 * specified in RTP frame, setting USC frame frametype to 0, setting bitrate 148 * of USC frame to bitrate info of codec_data. Implement this callback when 149 * the default behaviour is unapplicable. 145 150 */ 146 typedef void (*frm_attr_cb)(void *frame, int frame_size, 147 int *bitrate, int *frametype); 148 149 /* Parse frames of a packet, returning PJ_SUCCESS on success. This is useful 150 * for parsing a packet that contains multiple frames, while each frame may 151 * be an SID frame or audio frame, this is also useful for multirate codec, 152 * i.e: AMR. 151 typedef void (*predecode_cb)(ipp_private_t *codec_data, 152 const pjmedia_frame *rtp_frame, 153 USC_Bitstream *usc_frame); 154 155 /* Parse frames from a packet. Default behaviour of frame parsing is 156 * just separating frames based on calculating frame length derived 157 * from bitrate. Implement this callback when the default behaviour is 158 * unapplicable. 153 159 */ 154 160 typedef pj_status_t (*parse_cb)(ipp_private_t *codec_data, void *pkt, … … 156 162 unsigned *frame_cnt, pjmedia_frame frames[]); 157 163 158 /* Pack frames into a packet. 164 /* Pack frames into a packet. Default behaviour of packing frames is 165 * just stacking the frames with octet aligned without adding any 166 * payload header. Implement this callback when the default behaviour is 167 * unapplicable. 159 168 */ 160 169 typedef pj_status_t (*pack_cb)(ipp_private_t *codec_data, void *pkt, … … 163 172 164 173 165 /* Callback implementations. */ 166 static void frm_attr_g723(void *frame, int frame_size, 167 int *bitrate, int *frametype); 168 static void frm_attr_g729(void *frame, int frame_size, 169 int *bitrate, int *frametype); 170 171 static pj_status_t parse_g723(ipp_private_t *codec_data, void *pkt, 174 /* Custom callback implementations. */ 175 static void predecode_g723( ipp_private_t *codec_data, 176 const pjmedia_frame *rtp_frame, 177 USC_Bitstream *usc_frame); 178 static pj_status_t parse_g723( ipp_private_t *codec_data, void *pkt, 179 pj_size_t pkt_size, const pj_timestamp *ts, 180 unsigned *frame_cnt, pjmedia_frame frames[]); 181 182 static void predecode_g729( ipp_private_t *codec_data, 183 const pjmedia_frame *rtp_frame, 184 USC_Bitstream *usc_frame); 185 186 static void predecode_amr( ipp_private_t *codec_data, 187 const pjmedia_frame *rtp_frame, 188 USC_Bitstream *usc_frame); 189 static pj_status_t parse_amr( ipp_private_t *codec_data, void *pkt, 172 190 pj_size_t pkt_size, const pj_timestamp *ts, 173 191 unsigned *frame_cnt, pjmedia_frame frames[]); 174 static pj_status_t parse_amr(ipp_private_t *codec_data, void *pkt, 175 pj_size_t pkt_size, const pj_timestamp *ts, 176 unsigned *frame_cnt, pjmedia_frame frames[]); 177 static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt, 178 pj_size_t *pkt_size, pj_size_t max_pkt_size); 192 static pj_status_t pack_amr( ipp_private_t *codec_data, void *pkt, 193 pj_size_t *pkt_size, pj_size_t max_pkt_size); 179 194 180 195 … … 195 210 int has_native_plc; /* Codec has internal PLC? */ 196 211 197 frm_attr_cb frm_attr; /* Callback to get frame attribute */ 212 predecode_cb predecode; /* Callback to translate RTP frame 213 into USC frame */ 198 214 parse_cb parse; /* Callback to parse bitstream */ 199 215 pack_cb pack; /* Callback to pack bitstream */ … … 205 221 {1, "AMR", PJMEDIA_RTP_PT_AMR, &USC_GSMAMR_Fxns, 8000, 1, 160, 206 222 5900, 12200, 4, 1, 1, 207 NULL, &parse_amr, &pack_amr 223 &predecode_amr, &parse_amr, &pack_amr 224 }, 225 # endif 226 227 # if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB) && PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB != 0 228 {1, "AMR-WB", PJMEDIA_RTP_PT_AMRWB, &USC_AMRWB_Fxns, 16000, 1, 320, 229 15850, 23850, 4, 1, 1, 230 &predecode_amr, &parse_amr, &pack_amr 208 231 }, 209 232 # endif … … 218 241 {1, "G729", PJMEDIA_RTP_PT_G729, &USC_G729AFP_Fxns, 8000, 1, 80, 219 242 8000, 11800, 2, 0, 1, 220 & frm_attr_g729, NULL, NULL243 &predecode_g729, NULL, NULL 221 244 }, 222 245 # endif … … 226 249 {1, "G723", PJMEDIA_RTP_PT_G723, &USC_G723_Fxns, 8000, 1, 240, 227 250 5300, 6300, 1, 1, 1, 228 & frm_attr_g723, &parse_g723, NULL251 &predecode_g723, &parse_g723, NULL 229 252 }, 230 253 # endif … … 266 289 267 290 static int amr_get_mode(unsigned bitrate); 268 static void amr_predecode(pj_bool_t AMRWB, pjmedia_frame *f,269 int *frametype, int *bitrate);270 291 271 292 /* … … 800 821 pj_int16_t *pcm_in = (pj_int16_t*)input->buf; 801 822 pj_int8_t *bits_out = (pj_int8_t*) output->buf; 823 pj_uint8_t pt; 802 824 803 825 /* Invoke external VAD if codec has no internal VAD */ … … 830 852 nsamples = input->size >> 1; 831 853 samples_per_frame=ipp_codec[codec_data->codec_idx].samples_per_frame; 854 pt = ipp_codec[codec_data->codec_idx].pt; 832 855 833 856 PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, … … 850 873 #if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_AMR) && PJMEDIA_HAS_INTEL_IPP_CODEC_AMR != 0 851 874 /* For AMR: reserve the first byte for frame info */ 852 if ( ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR) {875 if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) { 853 876 ++out.pBuffer; 854 877 } … … 861 884 #if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_AMR) && PJMEDIA_HAS_INTEL_IPP_CODEC_AMR != 0 862 885 /* For AMR: put info (frametype, degraded, last frame) in the first byte */ 863 if ( ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR) {886 if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) { 864 887 pj_uint8_t *info = (pj_uint8_t*)bits_out; 865 888 … … 871 894 * bit 7 : quality flag 872 895 */ 873 if (out.frametype == 1 || out.frametype == 2 || out.frametype == 7) { 896 if (out.frametype == 0 || out.frametype == 4 || 897 (pt == PJMEDIA_RTP_PT_AMR && out.frametype == 5) || 898 (pt == PJMEDIA_RTP_PT_AMRWB && out.frametype == 6)) 899 { 900 /* Speech */ 901 *info = (char)amr_get_mode(out.bitrate); 902 /* Degraded */ 903 if (out.frametype == 5 || out.frametype == 6) 904 *info |= 0x80; 905 } else if (out.frametype == 1 || out.frametype == 2 || 906 (pt == PJMEDIA_RTP_PT_AMR && out.frametype == 6) || 907 (pt == PJMEDIA_RTP_PT_AMRWB && out.frametype == 7)) 908 { 874 909 /* SID */ 875 *info = 8;910 *info = pt == PJMEDIA_RTP_PT_AMRWB? 9 : 8; 876 911 /* Degraded */ 877 if (out.frametype == 7)912 if (out.frametype == 6 || out.frametype == 7) 878 913 *info |= 0x80; 879 } else if (out.frametype == 3){914 } else { 880 915 /* Untransmited */ 881 916 *info = 15; 882 917 out.nbytes = 1; 883 } else {884 /* Normal */885 *info = (char)amr_get_mode(out.bitrate);886 /* Degraded */887 if (out.frametype != 0)888 *info |= 0x80;889 918 } 890 919 … … 936 965 pj_uint8_t pt; 937 966 967 pt = ipp_codec[codec_data->codec_idx].pt; 938 968 samples_per_frame = ipp_codec[codec_data->codec_idx].samples_per_frame; 939 969 … … 942 972 943 973 if (input->type == PJMEDIA_FRAME_TYPE_AUDIO) { 944 in.nbytes = input->size; 945 in.pBuffer = (char*)input->buf; 946 if (ipp_codec[codec_data->codec_idx].frm_attr) { 947 ipp_codec[codec_data->codec_idx].frm_attr(input->buf, input->size, 948 &in.bitrate, 949 &in.frametype); 974 if (ipp_codec[codec_data->codec_idx].predecode) { 975 ipp_codec[codec_data->codec_idx].predecode(codec_data, input, &in); 950 976 } else { 951 977 /* Most IPP codecs have frametype==0 for speech frame */ 978 in.pBuffer = (char*)input->buf; 979 in.nbytes = input->size; 952 980 in.frametype = 0; 953 981 in.bitrate = codec_data->info->params.modes.bitrate; … … 955 983 956 984 out.pBuffer = output->buf; 957 958 #if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_AMR) && PJMEDIA_HAS_INTEL_IPP_CODEC_AMR != 0 959 /* For AMR: unorder the sensitivity order */ 960 if (ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR) { 961 pjmedia_frame input_ = *input; 962 amr_predecode(PJ_FALSE, &input_, &in.frametype, &in.bitrate); 963 in.nbytes = input_.size; 964 } 965 } 966 #endif 985 } 967 986 968 987 if (input->type != PJMEDIA_FRAME_TYPE_AUDIO || … … 979 998 #if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_G726) && PJMEDIA_HAS_INTEL_IPP_CODEC_G726 != 0 980 999 /* For G.726: amplify decoding result (USC G.726 encoder deamplified it) */ 981 pt = ipp_codec[codec_data->codec_idx].pt;982 1000 if (pt == PJMEDIA_RTP_PT_G726_16 || pt == PJMEDIA_RTP_PT_G726_24 || 983 1001 pt == PJMEDIA_RTP_PT_G726_32 || pt == PJMEDIA_RTP_PT_G726_40) … … 1037 1055 #if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_G729) && PJMEDIA_HAS_INTEL_IPP_CODEC_G729 != 0 1038 1056 1039 static void frm_attr_g729(void *frame, int frame_size, 1040 int *bitrate, int *frametype) 1041 { 1042 PJ_UNUSED_ARG(frame); 1043 1044 switch (frame_size) { 1057 static void predecode_g729( ipp_private_t *codec_data, 1058 const pjmedia_frame *rtp_frame, 1059 USC_Bitstream *usc_frame) 1060 { 1061 switch (rtp_frame->size) { 1045 1062 case 2: 1046 1063 /* SID */ 1047 *frametype = 1;1048 *bitrate = 8000;1064 usc_frame->frametype = 1; 1065 usc_frame->bitrate = codec_data->info->params.modes.bitrate; 1049 1066 break; 1050 1067 case 8: 1051 1068 /* G729D */ 1052 *frametype = 2;1053 *bitrate = 6400;1069 usc_frame->frametype = 2; 1070 usc_frame->bitrate = 6400; 1054 1071 break; 1055 1072 case 10: 1056 1073 /* G729 */ 1057 *frametype = 3;1058 *bitrate = 8000;1074 usc_frame->frametype = 3; 1075 usc_frame->bitrate = 8000; 1059 1076 break; 1060 1077 case 15: 1061 1078 /* G729E */ 1062 *frametype = 4;1063 *bitrate = 11800;1079 usc_frame->frametype = 4; 1080 usc_frame->bitrate = 11800; 1064 1081 break; 1065 1082 default: 1066 *frametype = 0;1067 *bitrate = 0;1083 usc_frame->frametype = 0; 1084 usc_frame->bitrate = 0; 1068 1085 break; 1069 1086 } 1087 1088 usc_frame->pBuffer = rtp_frame->buf; 1089 usc_frame->nbytes = rtp_frame->size; 1070 1090 } 1071 1091 … … 1075 1095 #if defined(PJMEDIA_HAS_INTEL_IPP_CODEC_G723) && PJMEDIA_HAS_INTEL_IPP_CODEC_G723 != 0 1076 1096 1077 static void frm_attr_g723(void *frame, int frame_size, 1078 int *bitrate, int *frametype) 1097 static void predecode_g723( ipp_private_t *codec_data, 1098 const pjmedia_frame *rtp_frame, 1099 USC_Bitstream *usc_frame) 1079 1100 { 1080 1101 int i, HDR = 0; 1081 pj_uint8_t *f = (pj_uint8_t*) frame;1082 1083 PJ_UNUSED_ARG( frame_size);1102 pj_uint8_t *f = (pj_uint8_t*)rtp_frame->buf; 1103 1104 PJ_UNUSED_ARG(codec_data); 1084 1105 1085 1106 for (i = 0; i < 2; ++i){ … … 1089 1110 } 1090 1111 1091 *bitrate = HDR == 0? 6300 : 5300; 1092 *frametype = 0; 1112 usc_frame->pBuffer = rtp_frame->buf; 1113 usc_frame->nbytes = rtp_frame->size; 1114 usc_frame->bitrate = HDR == 0? 6300 : 5300; 1115 usc_frame->frametype = 0; 1093 1116 } 1094 1117 … … 1653 1676 }; 1654 1677 1655 static pj_uint8_t AMRNB_framelen[ ]=1656 {12, 13, 15, 17, 19, 20, 26, 31, 5 };1657 static pj_uint 8_t AMRNB_framelenbits[] =1678 static pj_uint8_t AMRNB_framelen[16] = 1679 {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 5}; 1680 static pj_uint16_t AMRNB_framelenbits[9] = 1658 1681 {95, 103, 118, 134, 148, 159, 204, 244, 39}; 1659 static pj_uint 32_t AMRNB_bitrates[]=1682 static pj_uint16_t AMRNB_bitrates[8] = 1660 1683 {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; 1684 1685 static pj_uint8_t AMRWB_framelen[16] = 1686 {17, 23, 32, 37, 40, 46, 50, 58, 60, 5, 0, 0, 0, 0, 0, 5}; 1687 static pj_uint16_t AMRWB_framelenbits[10] = 1688 {132, 177, 253, 285, 317, 365, 397, 461, 477, 40}; 1689 static pj_uint16_t AMRWB_bitrates[9] = 1690 {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850}; 1661 1691 1662 1692 … … 1706 1736 } 1707 1737 1738 /* Rearrange AMR bitstream of rtp_frame: 1739 * - make the start_bit to be 0 1740 * - if it is speech frame, reorder bitstream from sensitivity bits order 1741 * to encoder bits order. 1742 */ 1743 static void predecode_amr( ipp_private_t *codec_data, 1744 const pjmedia_frame *rtp_frame, 1745 USC_Bitstream *usc_frame) 1746 { 1747 pj_uint8_t FT, Q; 1748 pj_int8_t amr_bits[477 + 7] = {0}; 1749 pj_int8_t *p_amr_bits = &amr_bits[0]; 1750 unsigned i; 1751 /* read cursor */ 1752 pj_uint8_t *r = (pj_uint8_t*)rtp_frame->buf; 1753 pj_uint8_t start_bit; 1754 /* write cursor */ 1755 pj_uint8_t *w = (pj_uint8_t*)rtp_frame->buf; 1756 /* env vars for AMR or AMRWB */ 1757 pj_bool_t AMRWB; 1758 pj_uint8_t SID_FT = 8; 1759 pj_uint8_t *framelen_tbl = AMRNB_framelen; 1760 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits; 1761 pj_uint16_t *bitrate_tbl = AMRNB_bitrates; 1762 pj_int16_t **order_map = AMRNB_ordermaps; 1763 1764 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB; 1765 if (AMRWB) { 1766 SID_FT = 9; 1767 framelen_tbl = AMRWB_framelen; 1768 framelenbit_tbl = AMRWB_framelenbits; 1769 bitrate_tbl = AMRWB_bitrates; 1770 order_map = AMRWB_ordermaps; 1771 } 1772 1773 start_bit = (pj_uint8_t)((rtp_frame->bit_info & 0x0700) >> 8); 1774 FT = (pj_uint8_t)(rtp_frame->bit_info & 0x0F); 1775 Q = (pj_uint8_t)((rtp_frame->bit_info >> 16) & 0x01); 1776 1777 /* unpack AMR bitstream if there is any data */ 1778 if (FT <= SID_FT) { 1779 i = 0; 1780 if (start_bit) { 1781 for (; i < (unsigned)(8-start_bit); ++i) 1782 *p_amr_bits++ = (pj_uint8_t)(*r >> (7-start_bit-i)) & 1; 1783 ++r; 1784 } 1785 for(; i < framelenbit_tbl[FT]; i += 8) { 1786 *p_amr_bits++ = (*r >> 7) & 1; 1787 *p_amr_bits++ = (*r >> 6) & 1; 1788 *p_amr_bits++ = (*r >> 5) & 1; 1789 *p_amr_bits++ = (*r >> 4) & 1; 1790 *p_amr_bits++ = (*r >> 3) & 1; 1791 *p_amr_bits++ = (*r >> 2) & 1; 1792 *p_amr_bits++ = (*r >> 1) & 1; 1793 *p_amr_bits++ = (*r ) & 1; 1794 ++r; 1795 } 1796 } 1797 1798 if (FT < SID_FT) { 1799 /* Speech */ 1800 pj_int16_t *order_map_; 1801 1802 order_map_ = order_map[FT]; 1803 pj_bzero(rtp_frame->buf, rtp_frame->size); 1804 for(i = 0; i < framelenbit_tbl[FT]; ++i) { 1805 if (amr_bits[i]) { 1806 pj_uint16_t bitpos; 1807 bitpos = order_map_[i]; 1808 w[bitpos>>3] |= 1 << (7 - (bitpos % 8)); 1809 } 1810 } 1811 usc_frame->nbytes = framelen_tbl[FT]; 1812 if (Q) 1813 usc_frame->frametype = 0; 1814 else 1815 usc_frame->frametype = AMRWB ? 6 : 5; 1816 usc_frame->bitrate = bitrate_tbl[FT]; 1817 } else if (FT == SID_FT) { 1818 /* SID */ 1819 pj_uint8_t w_bitptr = 0; 1820 pj_uint8_t STI; 1821 pj_uint8_t FT_; 1822 1823 STI = amr_bits[35]; 1824 if (AMRWB) 1825 FT_ = (amr_bits[36] << 3) | (amr_bits[37] << 2) | (amr_bits[38] << 1) | amr_bits[39]; 1826 else 1827 FT_ = (amr_bits[36] << 2) | (amr_bits[37] << 1) | amr_bits[38]; 1828 1829 pj_bzero(rtp_frame->buf, rtp_frame->size); 1830 for(i = 0; i < framelenbit_tbl[FT]; ++i) { 1831 if (amr_bits[i]) 1832 *w |= (1 << (7-w_bitptr)); 1833 1834 if (++w_bitptr == 8) { 1835 ++w; 1836 w_bitptr = 0; 1837 } 1838 } 1839 1840 usc_frame->nbytes = 5; 1841 if (Q) 1842 usc_frame->frametype = STI? 2 : 1; 1843 else 1844 usc_frame->frametype = AMRWB ? 7 : 6; 1845 1846 usc_frame->bitrate = bitrate_tbl[FT_]; 1847 } else { 1848 /* NO DATA */ 1849 usc_frame->nbytes = 0; 1850 usc_frame->frametype = 3; 1851 usc_frame->bitrate = 0; 1852 } 1853 1854 usc_frame->pBuffer = rtp_frame->buf; 1855 } 1708 1856 1709 1857 static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt, … … 1713 1861 pj_uint8_t CMR = 15; /* We don't request any code mode */ 1714 1862 pj_uint8_t octet_aligned = 0; /* default==0 when SDP not specifying */ 1715 1716 1863 /* Write cursor */ 1717 1864 pj_uint8_t *w = (pj_uint8_t*)pkt; 1718 1865 pj_uint8_t w_bitptr = 0; 1719 1720 1866 /* Read cursor */ 1721 1867 pj_uint8_t *r; 1722 1723 PJ_UNUSED_ARG(codec_data); 1868 /* env vars for AMR or AMRWB */ 1869 pj_bool_t AMRWB; 1870 pj_uint8_t SID_FT = 8; 1871 pj_uint8_t *framelen_tbl = AMRNB_framelen; 1872 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits; 1873 pj_uint16_t *bitrate_tbl = AMRNB_bitrates; 1874 pj_int16_t **order_map = AMRNB_ordermaps; 1875 1876 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB; 1877 if (AMRWB) { 1878 SID_FT = 9; 1879 framelen_tbl = AMRWB_framelen; 1880 framelenbit_tbl = AMRWB_framelenbits; 1881 bitrate_tbl = AMRWB_bitrates; 1882 order_map = AMRWB_ordermaps; 1883 } 1724 1884 1725 1885 PJ_TODO(Make_sure_buffer_is_enough_for_packing_AMR_packet); … … 1747 1907 Q = (*r & 0x80) == 0; 1748 1908 1749 pj_assert( (FT >=0 && FT <= 8)|| FT == 14 || FT == 15);1909 pj_assert(FT <= SID_FT || FT == 14 || FT == 15); 1750 1910 TOC = (pj_uint8_t)((F<<5) | (FT<<1) | Q); 1751 1911 … … 1771 1931 } 1772 1932 1773 if (FT == 14 || FT == 15) 1933 if (FT > SID_FT) 1934 /* NO DATA */ 1774 1935 r += 1; 1775 1936 else 1776 r += AMRNB_framelen[FT] + 1;1937 r += framelen_tbl[FT] + 1; 1777 1938 1778 1939 /* Last frame */ … … 1792 1953 F = (*r & 0x40) == 0; 1793 1954 FT = (*r & 0x0F); 1794 pj_assert( (FT >=0 && FT <= 8)|| FT == 14 || FT == 15);1955 pj_assert(FT <= SID_FT || FT == 14 || FT == 15); 1795 1956 1796 1957 ++r; 1797 if (FT == 14 || FT == 15) {1958 if (FT > SID_FT) { 1798 1959 if (!F) 1799 1960 break; … … 1802 1963 1803 1964 /* Unpack bits */ 1804 for(i = 0; i < AMRNB_framelen[FT]; ++i) {1965 for(i = 0; i < framelen_tbl[FT]; ++i) { 1805 1966 *p_amr_bits++ = (*r >> 7) & 1; 1806 1967 *p_amr_bits++ = (*r >> 6) & 1; … … 1814 1975 } 1815 1976 1816 if (FT == 8) { 1817 /* SID */ 1818 pj_uint8_t STI = 0; 1819 1820 amr_bits[35] = (STI & 1); 1821 amr_bits[36] = (FT >> 2) & 1; 1822 amr_bits[37] = (FT >> 1) & 1; 1823 amr_bits[38] = (FT) & 1; 1824 1977 if (FT < SID_FT) { 1978 /* Speech */ 1979 pj_int16_t *order_map_; 1980 1981 /* Put bits in the packet, sensitivity descending ordered */ 1982 order_map_ = order_map[FT]; 1825 1983 if (w_bitptr == 0) *w = 0; 1826 for(i = 0; i < AMRNB_framelenbits[FT]; ++i) { 1827 if (amr_bits[i]) 1984 for(i = 0; i < framelenbit_tbl[FT]; ++i) { 1985 pj_uint8_t bit; 1986 bit = amr_bits[order_map_[i]]; 1987 1988 if (bit) 1828 1989 *w |= (1 << (7-w_bitptr)); 1829 1990 … … 1839 2000 w_bitptr = 0; 1840 2001 } 1841 } else { 1842 /* Speech */ 1843 pj_int16_t *order_map; 1844 1845 /* Put bits in the packet, sensitivity descending ordered */ 1846 order_map = AMRNB_ordermaps[FT]; 2002 } else if (FT == SID_FT) { 2003 /* SID */ 2004 pj_uint8_t STI = 0; 2005 2006 amr_bits[35] = (STI & 1); 2007 2008 if (AMRWB) { 2009 amr_bits[36] = (FT >> 3) & 1; 2010 amr_bits[37] = (FT >> 2) & 1; 2011 amr_bits[38] = (FT >> 1) & 1; 2012 amr_bits[39] = (FT) & 1; 2013 } else { 2014 amr_bits[36] = (FT >> 2) & 1; 2015 amr_bits[37] = (FT >> 1) & 1; 2016 amr_bits[38] = (FT) & 1; 2017 } 2018 1847 2019 if (w_bitptr == 0) *w = 0; 1848 for(i = 0; i < AMRNB_framelenbits[FT]; ++i) { 1849 pj_uint8_t bit; 1850 bit = amr_bits[order_map[i]]; 1851 1852 if (bit) 2020 for(i = 0; i < framelenbit_tbl[FT]; ++i) { 2021 if (amr_bits[i]) 1853 2022 *w |= (1 << (7-w_bitptr)); 1854 2023 … … 1882 2051 /* Parse AMR payload into frames. Frame.bit_info will contain start_bit and 1883 2052 * AMR frame type, it is mapped as below (bit 0:MSB - bit 31:LSB) 1884 * - bit 0-16: unused2053 * - bit 0-16: degraded quality flag (Q) 1885 2054 * - bit 17-24: start_bit 1886 * - bit 25-32: frame_type 2055 * - bit 25-32: frame_type (FT) 1887 2056 */ 1888 2057 static pj_status_t parse_amr(ipp_private_t *codec_data, void *pkt, … … 1892 2061 unsigned cnt = 0; 1893 2062 pj_timestamp ts_ = *ts; 1894 1895 2063 /* Settings */ 1896 2064 pj_uint8_t CMR = 15; /* See if remote request code mode */ 1897 2065 pj_uint8_t octet_aligned = 0; /* default==0 when SDP not specifying */ 1898 1899 2066 /* Read cursor */ 1900 2067 pj_uint8_t r_bitptr = 0; 1901 2068 pj_uint8_t *r = (pj_uint8_t*)pkt; 2069 /* env vars for AMR or AMRWB */ 2070 pj_bool_t AMRWB; 2071 pj_uint8_t SID_FT = 8; 2072 pj_uint8_t *framelen_tbl = AMRNB_framelen; 2073 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits; 1902 2074 1903 2075 PJ_UNUSED_ARG(pkt_size); 2076 2077 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB; 2078 if (AMRWB) { 2079 SID_FT = 9; 2080 framelen_tbl = AMRWB_framelen; 2081 framelenbit_tbl = AMRWB_framelenbits; 2082 } 1904 2083 1905 2084 *frame_cnt = 0; … … 1938 2117 Q = TOC & 1; 1939 2118 1940 if (!((FT >=0 && FT <= 8) || FT == 14 || FT == 15)) 2119 if (FT > SID_FT && FT < 14) { 2120 pj_assert(!"Invalid AMR frametype, stream may be corrupted!"); 1941 2121 break; 2122 } 1942 2123 1943 2124 if (octet_aligned) { … … 1947 2128 1948 2129 /* Set frame attributes */ 1949 if (FT != 14 && FT != 15) { 1950 frames[cnt].bit_info = FT; 1951 frames[cnt].timestamp = ts_; 1952 frames[cnt].type = PJMEDIA_FRAME_TYPE_AUDIO; 1953 1954 ++cnt; 1955 } 2130 frames[cnt].bit_info = FT | (Q << 16); 2131 frames[cnt].timestamp = ts_; 2132 frames[cnt].type = PJMEDIA_FRAME_TYPE_AUDIO; 2133 1956 2134 ts_.u64 += ipp_codec[codec_data->codec_idx].samples_per_frame; 2135 ++cnt; 1957 2136 1958 2137 if (!F || cnt == *frame_cnt) … … 1967 2146 unsigned FT; 1968 2147 1969 FT = frames[cnt].bit_info ;2148 FT = frames[cnt].bit_info & 0x0F; 1970 2149 1971 2150 frames[cnt].bit_info |= (r_bitptr << 8); … … 1973 2152 1974 2153 if (octet_aligned) { 1975 r += AMRNB_framelen[FT];1976 frames[cnt].size = AMRNB_framelen[FT];2154 r += framelen_tbl[FT]; 2155 frames[cnt].size = framelen_tbl[FT]; 1977 2156 } else { 1978 unsigned adv_bit; 1979 1980 adv_bit = AMRNB_framelenbits[FT] + r_bitptr; 1981 r += adv_bit >> 3; 1982 r_bitptr = (pj_uint8_t)(adv_bit % 8); 1983 1984 frames[cnt].size = adv_bit >> 3; 1985 if (r_bitptr) 1986 ++frames[cnt].size; 2157 if (FT == 14 || FT == 15) { 2158 /* NO DATA */ 2159 frames[cnt].size = 0; 2160 } else { 2161 unsigned adv_bit; 2162 2163 adv_bit = framelenbit_tbl[FT] + r_bitptr; 2164 r += adv_bit >> 3; 2165 r_bitptr = (pj_uint8_t)(adv_bit % 8); 2166 2167 frames[cnt].size = adv_bit >> 3; 2168 if (r_bitptr) 2169 ++frames[cnt].size; 2170 } 1987 2171 } 1988 2172 ++cnt; … … 1990 2174 1991 2175 return PJ_SUCCESS; 1992 }1993 1994 /* Rearrange bits in the frame so its start_bit is 0 and also1995 * unorder bitstream (off the sensitivity order) if the frame1996 * contains speech (not SID frame).1997 */1998 static void amr_predecode(pj_bool_t AMRWB, pjmedia_frame *f,1999 int *frametype, int *bitrate)2000 {2001 pj_uint8_t FT;2002 pj_int8_t amr_bits[477 + 7] = {0};2003 pj_int8_t *p_amr_bits = &amr_bits[0];2004 unsigned i;2005 /* read cursor */2006 pj_uint8_t *r = (pj_uint8_t*)f->buf;2007 pj_uint8_t start_bit;2008 /* write cursor */2009 pj_uint8_t *w = (pj_uint8_t*)f->buf;2010 2011 PJ_UNUSED_ARG(AMRWB);2012 2013 start_bit = (pj_uint8_t)((f->bit_info & 0xFF00) >> 8);2014 FT = (pj_uint8_t)(f->bit_info & 0xFF);2015 2016 /* unpack AMR bitstream */2017 i = 0;2018 if (start_bit) {2019 for (; i < (unsigned)(8-start_bit); ++i)2020 *p_amr_bits++ = (pj_uint8_t)(*r >> (7-start_bit-i)) & 1;2021 ++r;2022 }2023 for(; i < AMRNB_framelenbits[FT]; i += 8) {2024 *p_amr_bits++ = (*r >> 7) & 1;2025 *p_amr_bits++ = (*r >> 6) & 1;2026 *p_amr_bits++ = (*r >> 5) & 1;2027 *p_amr_bits++ = (*r >> 4) & 1;2028 *p_amr_bits++ = (*r >> 3) & 1;2029 *p_amr_bits++ = (*r >> 2) & 1;2030 *p_amr_bits++ = (*r >> 1) & 1;2031 *p_amr_bits++ = (*r ) & 1;2032 ++r;2033 }2034 2035 if (FT >= 0 && FT <= 7) {2036 /* Speech */2037 pj_int16_t *order_map;2038 2039 order_map = AMRNB_ordermaps[FT];2040 pj_bzero(f->buf, f->size);2041 for(i = 0; i < AMRNB_framelenbits[FT]; ++i) {2042 if (amr_bits[i]) {2043 pj_uint16_t bitpos;2044 bitpos = order_map[i];2045 w[bitpos>>3] |= 1 << (7 - (bitpos % 8));2046 }2047 }2048 f->size = AMRNB_framelen[FT];2049 *frametype = 0;2050 *bitrate = AMRNB_bitrates[FT];2051 } else {2052 /* SID */2053 pj_uint8_t w_bitptr = 0;2054 pj_uint8_t STI;2055 pj_uint8_t mode;2056 2057 STI = amr_bits[35];2058 mode = (amr_bits[36] << 2) | (amr_bits[37] << 1) | amr_bits[38];2059 2060 pj_bzero(f->buf, f->size);2061 for(i = 0; i < AMRNB_framelenbits[FT]; ++i) {2062 if (amr_bits[i])2063 *w |= (1 << (7-w_bitptr));2064 2065 if (++w_bitptr == 8) {2066 ++w;2067 w_bitptr = 0;2068 }2069 }2070 2071 f->size = 5;2072 *frametype = STI? 2 : 1;2073 *bitrate = AMRNB_bitrates[mode];2074 }2075 2176 } 2076 2177
Note: See TracChangeset
for help on using the changeset viewer.