support build-in speex to aac,controled by the root config keyword: speex2aac on/off
正在显示
18 个修改的文件
包含
582 行增加
和
11 行删除
.gitmodules
0 → 100644
| @@ -62,6 +62,9 @@ work_dir ./; | @@ -62,6 +62,9 @@ work_dir ./; | ||
| 62 | # @reamrk do not support reload. | 62 | # @reamrk do not support reload. |
| 63 | # default: off | 63 | # default: off |
| 64 | asprocess off; | 64 | asprocess off; |
| 65 | +# whether using build-in speex to aac transcoding | ||
| 66 | +# default: off | ||
| 67 | +speex2aac off; | ||
| 65 | 68 | ||
| 66 | ############################################################################################# | 69 | ############################################################################################# |
| 67 | # heartbeat/stats sections | 70 | # heartbeat/stats sections |
| @@ -928,6 +931,16 @@ vhost same.vhost.forward.srs.com { | @@ -928,6 +931,16 @@ vhost same.vhost.forward.srs.com { | ||
| 928 | # active-active for cdn to build high available fault tolerance system. | 931 | # active-active for cdn to build high available fault tolerance system. |
| 929 | # format: {ip}:{port} {ip_N}:{port_N} | 932 | # format: {ip}:{port} {ip_N}:{port_N} |
| 930 | forward 127.0.0.1:1936 127.0.0.1:1937; | 933 | forward 127.0.0.1:1936 127.0.0.1:1937; |
| 934 | + # forward_in_turn all publish stream to the specified server in turn. | ||
| 935 | + # this used to split/forward the current stream for transcode and make load balance | ||
| 936 | + # active-active for cdn to build high available fault tolerance system. | ||
| 937 | + # format: {ip}:{port} {ip_N}:{port_N} | ||
| 938 | + forward_in_turn 127.0.0.1:19351 127.0.0.1:19352; | ||
| 939 | + #if the forward server is same as this server , a origin,try use forward_peer, | ||
| 940 | + #the stream pushed from other forward peer will not forward any more in this server | ||
| 941 | + forward_peer 127.0.0.1:1936; | ||
| 942 | + #list out the servers which is not srs ,used in forward or forward_in_turn,and forward_peer for example,forward to some CDN | ||
| 943 | + forward_server_other 127.0.0.1:19351; | ||
| 931 | } | 944 | } |
| 932 | 945 | ||
| 933 | # the main comments for transcode | 946 | # the main comments for transcode |
trunk/conf/speex2aac.conf
0 → 100644
| 1 | -#!/bin/bash | ||
| 2 | - | ||
| 3 | ##################################################################################### | 1 | ##################################################################################### |
| 4 | # the main output dir, all configure and make output are in this dir. | 2 | # the main output dir, all configure and make output are in this dir. |
| 5 | ##################################################################################### | 3 | ##################################################################################### |
| @@ -125,6 +123,8 @@ if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = NO ]; then LibSSLRoot="${SRS | @@ -125,6 +123,8 @@ if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = NO ]; then LibSSLRoot="${SRS | ||
| 125 | # gperftools-2.1, for mem check and mem/cpu profile | 123 | # gperftools-2.1, for mem check and mem/cpu profile |
| 126 | LibGperfRoot=""; LibGperfFile="" | 124 | LibGperfRoot=""; LibGperfFile="" |
| 127 | if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS_DIR}/gperf/include"; LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_and_profiler.a"; fi | 125 | if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS_DIR}/gperf/include"; LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_and_profiler.a"; fi |
| 126 | +# codec libs:speex fdk-aac for SPEEX2AAC | ||
| 127 | +LibSpeex2aacRoot="${SRS_OBJS_DIR}/libs/include"; LibSpeex2aacfile="${SRS_OBJS_DIR}/libs/lib/libspeex.a ${SRS_OBJS_DIR}/libs/lib/libfdk-aac.a" | ||
| 128 | # the link options, always use static link | 128 | # the link options, always use static link |
| 129 | SrsLinkOptions="-ldl"; | 129 | SrsLinkOptions="-ldl"; |
| 130 | if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lssl -lcrypto"; fi fi | 130 | if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lssl -lcrypto"; fi fi |
| @@ -166,10 +166,18 @@ MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" | @@ -166,10 +166,18 @@ MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" | ||
| 166 | PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh | 166 | PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh |
| 167 | PROTOCOL_OBJS="${MODULE_OBJS[@]}" | 167 | PROTOCOL_OBJS="${MODULE_OBJS[@]}" |
| 168 | # | 168 | # |
| 169 | +#SPEEX2AAC speex to aac | ||
| 170 | +MODULE_ID="SPEEX2AAC" | ||
| 171 | +MODULE_DEPENDS=("CORE" "KERNEL") | ||
| 172 | +ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSpeex2aacRoot}) | ||
| 173 | +MODULE_FILES=("srs_tc_adc_speex" "srs_tc_aec_aac" "srs_tc_common") | ||
| 174 | +SPEEX2AAC_INCS="src/transcode"; MODULE_DIR=${SPEEX2AAC_INCS} . auto/modules.sh | ||
| 175 | +SPEEX2AAC_OBJS="${MODULE_OBJS[@]}" | ||
| 176 | +# | ||
| 169 | #App Module | 177 | #App Module |
| 170 | if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | 178 | if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then |
| 171 | MODULE_ID="APP" | 179 | MODULE_ID="APP" |
| 172 | - MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL") | 180 | + MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SPEEX2AAC") |
| 173 | ModuleLibIncs=(${LibSTRoot} ${LibHttpParserRoot} ${LibSSLRoot} ${SRS_OBJS_DIR}) | 181 | ModuleLibIncs=(${LibSTRoot} ${LibHttpParserRoot} ${LibSSLRoot} ${SRS_OBJS_DIR}) |
| 174 | MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_source" | 182 | MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_source" |
| 175 | "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream" | 183 | "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream" |
| @@ -202,8 +210,8 @@ LIBS_OBJS="${MODULE_OBJS[@]}" | @@ -202,8 +210,8 @@ LIBS_OBJS="${MODULE_OBJS[@]}" | ||
| 202 | #Main Module | 210 | #Main Module |
| 203 | if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | 211 | if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then |
| 204 | MODULE_ID="MAIN" | 212 | MODULE_ID="MAIN" |
| 205 | - MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP") | ||
| 206 | - ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibHttpParserRoot} ${LibSSLRoot}) | 213 | + MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP" "SPEEX2AAC") |
| 214 | + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibHttpParserRoot} ${LibSSLRoot} ${LibSpeex2aacRoot}) | ||
| 207 | MODULE_FILES=("srs_main_server" "srs_main_ingest_hls") | 215 | MODULE_FILES=("srs_main_server" "srs_main_ingest_hls") |
| 208 | # add each modules for main | 216 | # add each modules for main |
| 209 | for SRS_MODULE in ${SRS_MODULES[*]}; do | 217 | for SRS_MODULE in ${SRS_MODULES[*]}; do |
| @@ -229,9 +237,9 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | @@ -229,9 +237,9 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | ||
| 229 | done | 237 | done |
| 230 | # | 238 | # |
| 231 | # all depends libraries | 239 | # all depends libraries |
| 232 | - ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile} ${LibGperfFile}) | 240 | + ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile} ${LibGperfFile} ${LibSpeex2aacfile}) |
| 233 | # all depends objects | 241 | # all depends objects |
| 234 | - MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]}" | 242 | + MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]} ${SPEEX2AAC_OBJS[@]}" |
| 235 | LINK_OPTIONS="${SrsLinkOptions}${SrsGprofLink}${SrsGperfLink}" | 243 | LINK_OPTIONS="${SrsLinkOptions}${SrsGprofLink}${SrsGperfLink}" |
| 236 | # | 244 | # |
| 237 | # srs: srs(simple rtmp server) over st(state-threads) | 245 | # srs: srs(simple rtmp server) over st(state-threads) |
| @@ -258,10 +266,10 @@ if [ $SRS_UTEST = YES ]; then | @@ -258,10 +266,10 @@ if [ $SRS_UTEST = YES ]; then | ||
| 258 | MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol" | 266 | MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol" |
| 259 | "srs_utest_kernel" "srs_utest_core" "srs_utest_config" | 267 | "srs_utest_kernel" "srs_utest_core" "srs_utest_config" |
| 260 | "srs_utest_reload") | 268 | "srs_utest_reload") |
| 261 | - ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot}) | ||
| 262 | - ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile}) | 269 | + ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot} ${LibSpeex2aacRoot}) |
| 270 | + ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile} ${LibSpeex2aacfile}) | ||
| 263 | MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP") | 271 | MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP") |
| 264 | - MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]}" | 272 | + MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${SPEEX2AAC_OBJS[@]}" |
| 265 | LINK_OPTIONS="-lpthread ${SrsLinkOptions}" MODULE_DIR="src/utest" APP_NAME="srs_utest" . auto/utest.sh | 273 | LINK_OPTIONS="-lpthread ${SrsLinkOptions}" MODULE_DIR="src/utest" APP_NAME="srs_utest" . auto/utest.sh |
| 266 | fi | 274 | fi |
| 267 | 275 | ||
| @@ -349,6 +357,7 @@ else | @@ -349,6 +357,7 @@ else | ||
| 349 | server: _prepare_dir | 357 | server: _prepare_dir |
| 350 | @echo "build the srs(simple rtmp server) over st(state-threads)" | 358 | @echo "build the srs(simple rtmp server) over st(state-threads)" |
| 351 | ./scripts/version.sh | 359 | ./scripts/version.sh |
| 360 | + ./scripts/build_libs.sh | ||
| 352 | \$(MAKE) -f ${SRS_OBJS_DIR}/${SRS_MAKEFILE} srs | 361 | \$(MAKE) -f ${SRS_OBJS_DIR}/${SRS_MAKEFILE} srs |
| 353 | srs_ingest_hls: _prepare_dir | 362 | srs_ingest_hls: _prepare_dir |
| 354 | @echo "build the srs_ingest_hls for srs" | 363 | @echo "build the srs_ingest_hls for srs" |
trunk/scripts/build_libs.sh
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +mkdir -p objs | ||
| 3 | +root=$PWD | ||
| 4 | +if [ ! -d "$root/3rdparty/speex/.git" ]; then | ||
| 5 | + cd .. | ||
| 6 | + git submodule update --init | ||
| 7 | + cd trunk | ||
| 8 | +fi | ||
| 9 | +if [ "$1" == "-f" ]; then | ||
| 10 | + rm -rf objs/libs | ||
| 11 | +fi | ||
| 12 | +if [ ! -d "$root/objs/libs/include/speex" ]; then | ||
| 13 | + cd 3rdparty/speex && ./autogen.sh && ./configure --prefix=$root/objs/libs --enable-shared=no && make && make install | ||
| 14 | + cd $root | ||
| 15 | +fi | ||
| 16 | +if [ ! -d "$root/objs/libs/include/fdk-aac" ]; then | ||
| 17 | + cd 3rdparty/fdk-aac && ./autogen.sh && ./configure --prefix=$root/objs/libs --enable-shared=no && make && make install | ||
| 18 | +fi | ||
| 19 | + |
| @@ -463,6 +463,8 @@ SrsConfig::SrsConfig() | @@ -463,6 +463,8 @@ SrsConfig::SrsConfig() | ||
| 463 | root = new SrsConfDirective(); | 463 | root = new SrsConfDirective(); |
| 464 | root->conf_line = 0; | 464 | root->conf_line = 0; |
| 465 | root->name = "root"; | 465 | root->name = "root"; |
| 466 | + | ||
| 467 | + _speex2aac = false; | ||
| 466 | } | 468 | } |
| 467 | 469 | ||
| 468 | SrsConfig::~SrsConfig() | 470 | SrsConfig::~SrsConfig() |
| @@ -1005,6 +1007,8 @@ int SrsConfig::reload_conf(SrsConfig* conf) | @@ -1005,6 +1007,8 @@ int SrsConfig::reload_conf(SrsConfig* conf) | ||
| 1005 | return ret; | 1007 | return ret; |
| 1006 | } | 1008 | } |
| 1007 | 1009 | ||
| 1010 | + set_config_static(); | ||
| 1011 | + | ||
| 1008 | return ret; | 1012 | return ret; |
| 1009 | } | 1013 | } |
| 1010 | 1014 | ||
| @@ -1579,7 +1583,7 @@ int SrsConfig::check_config() | @@ -1579,7 +1583,7 @@ int SrsConfig::check_config() | ||
| 1579 | && n != "max_connections" && n != "daemon" && n != "heartbeat" | 1583 | && n != "max_connections" && n != "daemon" && n != "heartbeat" |
| 1580 | && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" | 1584 | && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" |
| 1581 | && n != "http_stream" && n != "http_server" && n != "stream_caster" | 1585 | && n != "http_stream" && n != "http_server" && n != "stream_caster" |
| 1582 | - && n != "utc_time" && n != "work_dir" && n != "asprocess" | 1586 | + && n != "utc_time" && n != "work_dir" && n != "asprocess" && n != "speex2aac" |
| 1583 | ) { | 1587 | ) { |
| 1584 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1588 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1585 | srs_error("unsupported directive %s, ret=%d", n.c_str(), ret); | 1589 | srs_error("unsupported directive %s, ret=%d", n.c_str(), ret); |
| @@ -2080,9 +2084,27 @@ int SrsConfig::check_config() | @@ -2080,9 +2084,27 @@ int SrsConfig::check_config() | ||
| 2080 | return ret; | 2084 | return ret; |
| 2081 | } | 2085 | } |
| 2082 | 2086 | ||
| 2087 | + | ||
| 2088 | + set_config_static(); | ||
| 2089 | + | ||
| 2083 | return ret; | 2090 | return ret; |
| 2084 | } | 2091 | } |
| 2085 | 2092 | ||
| 2093 | +void SrsConfig::set_config_static() | ||
| 2094 | +{ | ||
| 2095 | + SrsConfDirective* conf = root->get("speex2aac"); | ||
| 2096 | + if(conf){ | ||
| 2097 | + if(conf->arg0() == "on"){ | ||
| 2098 | + _speex2aac = true; | ||
| 2099 | + } | ||
| 2100 | + else | ||
| 2101 | + _speex2aac = false; | ||
| 2102 | + } | ||
| 2103 | + else | ||
| 2104 | + _speex2aac = false; | ||
| 2105 | + | ||
| 2106 | +} | ||
| 2107 | + | ||
| 2086 | int SrsConfig::parse_buffer(SrsConfigBuffer* buffer) | 2108 | int SrsConfig::parse_buffer(SrsConfigBuffer* buffer) |
| 2087 | { | 2109 | { |
| 2088 | int ret = ERROR_SUCCESS; | 2110 | int ret = ERROR_SUCCESS; |
| @@ -1141,6 +1141,18 @@ public: | @@ -1141,6 +1141,18 @@ public: | ||
| 1141 | * @return the disk device name to stat. NULL if not configed. | 1141 | * @return the disk device name to stat. NULL if not configed. |
| 1142 | */ | 1142 | */ |
| 1143 | virtual SrsConfDirective* get_stats_disk_device(); | 1143 | virtual SrsConfDirective* get_stats_disk_device(); |
| 1144 | + | ||
| 1145 | +public: | ||
| 1146 | + | ||
| 1147 | + /** | ||
| 1148 | + * the flag to indicate auto transcode with build-in modules | ||
| 1149 | + */ | ||
| 1150 | + bool _speex2aac; | ||
| 1151 | +private: | ||
| 1152 | + /** | ||
| 1153 | + * set the global static variables from config file | ||
| 1154 | + */ | ||
| 1155 | + void set_config_static(); | ||
| 1144 | }; | 1156 | }; |
| 1145 | 1157 | ||
| 1146 | namespace _srs_internal | 1158 | namespace _srs_internal |
| @@ -46,6 +46,7 @@ using namespace std; | @@ -46,6 +46,7 @@ using namespace std; | ||
| 46 | #include <srs_app_statistic.hpp> | 46 | #include <srs_app_statistic.hpp> |
| 47 | #include <srs_core_autofree.hpp> | 47 | #include <srs_core_autofree.hpp> |
| 48 | #include <srs_rtmp_utility.hpp> | 48 | #include <srs_rtmp_utility.hpp> |
| 49 | +#include <srs_tc_av_codec.hpp> | ||
| 49 | 50 | ||
| 50 | #define CONST_MAX_JITTER_MS 250 | 51 | #define CONST_MAX_JITTER_MS 250 |
| 51 | #define CONST_MAX_JITTER_MS_NEG -250 | 52 | #define CONST_MAX_JITTER_MS_NEG -250 |
| @@ -970,6 +971,8 @@ SrsSource::SrsSource() | @@ -970,6 +971,8 @@ SrsSource::SrsSource() | ||
| 970 | 971 | ||
| 971 | _srs_config->subscribe(this); | 972 | _srs_config->subscribe(this); |
| 972 | atc = false; | 973 | atc = false; |
| 974 | + _speex_opt = NULL; | ||
| 975 | + _aac_opt = NULL; | ||
| 973 | } | 976 | } |
| 974 | 977 | ||
| 975 | SrsSource::~SrsSource() | 978 | SrsSource::~SrsSource() |
| @@ -1013,6 +1016,15 @@ SrsSource::~SrsSource() | @@ -1013,6 +1016,15 @@ SrsSource::~SrsSource() | ||
| 1013 | #endif | 1016 | #endif |
| 1014 | 1017 | ||
| 1015 | srs_freep(_req); | 1018 | srs_freep(_req); |
| 1019 | + | ||
| 1020 | + if (_speex_opt){ | ||
| 1021 | + adc_spx.close_codec((tc_audio_opt *)_speex_opt); | ||
| 1022 | + _speex_opt = NULL; | ||
| 1023 | + } | ||
| 1024 | + if (_aac_opt) { | ||
| 1025 | + aec_aac.close_codec((tc_audio_opt *)_aac_opt); | ||
| 1026 | + _aac_opt = NULL; | ||
| 1027 | + } | ||
| 1016 | } | 1028 | } |
| 1017 | 1029 | ||
| 1018 | void SrsSource::dispose() | 1030 | void SrsSource::dispose() |
| @@ -1662,6 +1674,101 @@ int SrsSource::on_data(SrsCommonMessage* shared_data) | @@ -1662,6 +1674,101 @@ int SrsSource::on_data(SrsCommonMessage* shared_data) | ||
| 1662 | 1674 | ||
| 1663 | int SrsSource::on_audio(SrsCommonMessage* shared_audio) | 1675 | int SrsSource::on_audio(SrsCommonMessage* shared_audio) |
| 1664 | { | 1676 | { |
| 1677 | + int ret = ERROR_SUCCESS; | ||
| 1678 | + | ||
| 1679 | + if(_srs_config->_speex2aac && SrsFlvCodec::audio_is_speex(shared_audio->payload, shared_audio->size)){ | ||
| 1680 | + | ||
| 1681 | + if (NULL == _speex_opt){ | ||
| 1682 | + tc_audio_opt * speex_opt = new tc_audio_opt(); | ||
| 1683 | + _speex_opt = speex_opt; | ||
| 1684 | + speex_opt->sample_rate = 16000; | ||
| 1685 | + speex_opt->channels = 1; | ||
| 1686 | + speex_opt->frame_size = 320; | ||
| 1687 | + speex_opt->buffer_size = 640; | ||
| 1688 | + adc_spx.open_codec(speex_opt); | ||
| 1689 | + if (NULL == _aac_opt){ | ||
| 1690 | + tc_audio_opt * aac_opt = new tc_audio_opt(); | ||
| 1691 | + _aac_opt = aac_opt; | ||
| 1692 | + aac_opt->sample_rate = 16000; | ||
| 1693 | + aac_opt->channels = 1; | ||
| 1694 | + aac_opt->frame_size = 1024; | ||
| 1695 | + aac_opt->buffer_size = 2048; | ||
| 1696 | + aac_opt->audio_bitrate = 64000; | ||
| 1697 | + | ||
| 1698 | + aec_aac.open_codec(aac_opt); | ||
| 1699 | + char * buf = new char[aac_opt->extradata_size + 2]; | ||
| 1700 | + buf[0] = 0xAF; | ||
| 1701 | + buf[1] = 0x00; | ||
| 1702 | + memcpy(buf + 2, aac_opt->extradata, aac_opt->extradata_size); | ||
| 1703 | + SrsCommonMessage msg; | ||
| 1704 | + msg.header = shared_audio->header; | ||
| 1705 | + msg.payload = buf; | ||
| 1706 | + msg.size = aac_opt->extradata_size + 2; | ||
| 1707 | + ret = _on_audio(&msg); | ||
| 1708 | + freep(msg.payload); | ||
| 1709 | + if(ret != ERROR_SUCCESS){ | ||
| 1710 | + freep(shared_audio->payload); | ||
| 1711 | + return ret; | ||
| 1712 | + } | ||
| 1713 | + } | ||
| 1714 | + } | ||
| 1715 | + uint8_t* packet_data = (uint8_t *)shared_audio->payload + 1; | ||
| 1716 | + int packet_size = shared_audio->size - 1; | ||
| 1717 | + | ||
| 1718 | + char * payload = shared_audio->payload; | ||
| 1719 | + | ||
| 1720 | + do { | ||
| 1721 | + uint8_t out_data[1024]; | ||
| 1722 | + uint32_t out_size; | ||
| 1723 | + | ||
| 1724 | + int ret_spx = adc_spx.decode_frame((tc_audio_opt*)_speex_opt, packet_data, packet_size, out_data); | ||
| 1725 | + if (ret_spx >= 0) { | ||
| 1726 | +#if 0 | ||
| 1727 | + static FILE * fp = NULL; | ||
| 1728 | + if (!fp){ | ||
| 1729 | + fp = fopen("testout.pcm", "wb"); | ||
| 1730 | + } | ||
| 1731 | + | ||
| 1732 | + if (fp){ | ||
| 1733 | + fwrite(out_data, 1, 640, fp); | ||
| 1734 | + } | ||
| 1735 | +#endif | ||
| 1736 | + ((tc_audio_opt *)_aac_opt)->buffer_size = ((tc_audio_opt*)_speex_opt)->buffer_size; | ||
| 1737 | + | ||
| 1738 | + shared_audio->payload = new char[1024]; | ||
| 1739 | + out_size = 1022; | ||
| 1740 | + int ret_aac = aec_aac.encode_frame((tc_audio_opt *)_aac_opt, out_data, (uint8_t *)shared_audio->payload + 2 , &out_size); | ||
| 1741 | + if (ret_aac >= 0){ | ||
| 1742 | + if (out_size){ | ||
| 1743 | + shared_audio->payload[0] = 0xAF; | ||
| 1744 | + shared_audio->payload[1] = 0x01; | ||
| 1745 | + shared_audio->size = out_size +2; | ||
| 1746 | + ret = _on_audio(shared_audio); | ||
| 1747 | +#if 0 | ||
| 1748 | + static int max_out_size = 0; | ||
| 1749 | + if(out_size > max_out_size){ | ||
| 1750 | + max_out_size = out_size; | ||
| 1751 | + srs_trace("max_speex_aac_outsize:%d",max_out_size); | ||
| 1752 | + } | ||
| 1753 | +#endif | ||
| 1754 | + } | ||
| 1755 | + } | ||
| 1756 | + } | ||
| 1757 | + packet_data += ret_spx; | ||
| 1758 | + packet_size -= ret_spx; | ||
| 1759 | + | ||
| 1760 | + } while (packet_size > 0); | ||
| 1761 | + | ||
| 1762 | + freep(payload); | ||
| 1763 | + } | ||
| 1764 | + else { | ||
| 1765 | + return _on_audio(shared_audio); | ||
| 1766 | + } | ||
| 1767 | + return ret; | ||
| 1768 | +} | ||
| 1769 | + | ||
| 1770 | +int SrsSource::_on_audio(SrsCommonMessage* shared_audio) | ||
| 1771 | +{ | ||
| 1665 | int ret = ERROR_SUCCESS; | 1772 | int ret = ERROR_SUCCESS; |
| 1666 | 1773 | ||
| 1667 | // monotically increase detect. | 1774 | // monotically increase detect. |
| @@ -511,6 +511,8 @@ private: | @@ -511,6 +511,8 @@ private: | ||
| 511 | SrsSharedPtrMessage* cache_sh_video; | 511 | SrsSharedPtrMessage* cache_sh_video; |
| 512 | // the cached audio sequence header. | 512 | // the cached audio sequence header. |
| 513 | SrsSharedPtrMessage* cache_sh_audio; | 513 | SrsSharedPtrMessage* cache_sh_audio; |
| 514 | + void * _speex_opt; | ||
| 515 | + void * _aac_opt; | ||
| 514 | public: | 516 | public: |
| 515 | SrsSource(); | 517 | SrsSource(); |
| 516 | virtual ~SrsSource(); | 518 | virtual ~SrsSource(); |
| @@ -559,6 +561,7 @@ public: | @@ -559,6 +561,7 @@ public: | ||
| 559 | public: | 561 | public: |
| 560 | virtual int on_audio(SrsCommonMessage* audio); | 562 | virtual int on_audio(SrsCommonMessage* audio); |
| 561 | private: | 563 | private: |
| 564 | + virtual int _on_audio(SrsCommonMessage* audio); | ||
| 562 | virtual int on_audio_imp(SrsSharedPtrMessage* audio); | 565 | virtual int on_audio_imp(SrsSharedPtrMessage* audio); |
| 563 | public: | 566 | public: |
| 564 | virtual int on_video(SrsCommonMessage* video); | 567 | virtual int on_video(SrsCommonMessage* video); |
| @@ -266,6 +266,18 @@ bool SrsFlvCodec::audio_is_aac(char* data, int size) | @@ -266,6 +266,18 @@ bool SrsFlvCodec::audio_is_aac(char* data, int size) | ||
| 266 | return sound_format == SrsCodecAudioAAC; | 266 | return sound_format == SrsCodecAudioAAC; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | +bool SrsFlvCodec::audio_is_speex(char* data, int size) | ||
| 270 | +{ | ||
| 271 | + // 1bytes required. | ||
| 272 | + if (size < 1) { | ||
| 273 | + return false; | ||
| 274 | + } | ||
| 275 | + | ||
| 276 | + char sound_format = (*data >> 4) & 0x0F; | ||
| 277 | + | ||
| 278 | + return sound_format == SrsCodecAudioSpeex; | ||
| 279 | +} | ||
| 280 | + | ||
| 269 | bool SrsFlvCodec::video_is_acceptable(char* data, int size) | 281 | bool SrsFlvCodec::video_is_acceptable(char* data, int size) |
| 270 | { | 282 | { |
| 271 | // 1bytes required. | 283 | // 1bytes required. |
| @@ -223,6 +223,10 @@ public: | @@ -223,6 +223,10 @@ public: | ||
| 223 | */ | 223 | */ |
| 224 | static bool audio_is_aac(char* data, int size); | 224 | static bool audio_is_aac(char* data, int size); |
| 225 | /** | 225 | /** |
| 226 | + * check codec speex. | ||
| 227 | + */ | ||
| 228 | + static bool audio_is_speex(char* data, int size); | ||
| 229 | + /** | ||
| 226 | * check the video RTMP/flv header info, | 230 | * check the video RTMP/flv header info, |
| 227 | * @return true if video RTMP/flv header is ok. | 231 | * @return true if video RTMP/flv header is ok. |
| 228 | * @remark all type of audio is possible, no need to check audio. | 232 | * @remark all type of audio is possible, no need to check audio. |
trunk/src/transcode/srs_tc_adc_speex.cpp
0 → 100644
| 1 | +#include "speex/speex.h" | ||
| 2 | +#include "srs_tc_av_codec.hpp" | ||
| 3 | +#include "srs_tc_common.hpp" | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +typedef struct { | ||
| 7 | + SpeexBits bits; | ||
| 8 | + void *dec_state; | ||
| 9 | + int dec_frame_size; | ||
| 10 | + int dec_buffer_size; | ||
| 11 | + spx_int16_t* output_buffer; | ||
| 12 | +} handle_adc_spx_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +static int open_codec_spx(tc_audio_opt* opt) { | ||
| 16 | + handle_adc_spx_t* s = (handle_adc_spx_t*)calloc(1, sizeof(handle_adc_spx_t)); | ||
| 17 | + opt->handle = s; | ||
| 18 | + speex_bits_init(&s->bits); | ||
| 19 | + s->dec_state = speex_decoder_init(&speex_wb_mode); | ||
| 20 | + speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &s->dec_frame_size); | ||
| 21 | + s->dec_buffer_size = s->dec_frame_size * sizeof(spx_int16_t); | ||
| 22 | + opt->sample_rate = 16000; | ||
| 23 | + opt->channels = 1; | ||
| 24 | + opt->buffer_size = s->dec_buffer_size ; | ||
| 25 | + opt->frame_size = s->dec_frame_size; | ||
| 26 | + return 0; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +static int decode_frame_spx(tc_audio_opt* opt, uint8_t* inData, uint32_t inDataSize, uint8_t* outData) { | ||
| 31 | + handle_adc_spx_t* s = (handle_adc_spx_t*)opt->handle; | ||
| 32 | + int consumed = 0; | ||
| 33 | + if (speex_bits_remaining(&s->bits) < 5 || | ||
| 34 | + speex_bits_peek_unsigned(&s->bits, 5) == 0xF) { | ||
| 35 | + speex_bits_read_from(&s->bits, (char*)inData, inDataSize); | ||
| 36 | + consumed = inDataSize; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + int err = 0; | ||
| 40 | + if ((err = speex_decode_int(s->dec_state, &s->bits, (spx_int16_t *)outData)) == 0) { | ||
| 41 | + return consumed; | ||
| 42 | + } else { | ||
| 43 | + tc_log(LOG_LEVEL_ERROR, "speex_decode_int error: %d", err); | ||
| 44 | + return -1; | ||
| 45 | + } | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +static int close_codec_spx(tc_audio_opt* opt) { | ||
| 49 | + handle_adc_spx_t* s = (handle_adc_spx_t*)opt->handle; | ||
| 50 | + speex_decoder_destroy(s->dec_state); | ||
| 51 | + speex_bits_destroy(&s->bits); | ||
| 52 | + return 0; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | + | ||
| 56 | +const tc_av_codec_t adc_spx = { | ||
| 57 | + 11, | ||
| 58 | + "adc_spx", | ||
| 59 | + open_codec_spx, | ||
| 60 | + decode_frame_spx, | ||
| 61 | + NULL, | ||
| 62 | + close_codec_spx | ||
| 63 | +}; |
trunk/src/transcode/srs_tc_aec_aac.cpp
0 → 100644
| 1 | +#include "fdk-aac/aacenc_lib.h" | ||
| 2 | +#include "srs_tc_av_codec.hpp" | ||
| 3 | +#include "srs_tc_common.hpp" | ||
| 4 | + | ||
| 5 | +static const char *aac_get_error(AACENC_ERROR err) | ||
| 6 | +{ | ||
| 7 | + switch (err) { | ||
| 8 | + case AACENC_OK: | ||
| 9 | + return "No error"; | ||
| 10 | + case AACENC_INVALID_HANDLE: | ||
| 11 | + return "Invalid handle"; | ||
| 12 | + case AACENC_MEMORY_ERROR: | ||
| 13 | + return "Memory allocation error"; | ||
| 14 | + case AACENC_UNSUPPORTED_PARAMETER: | ||
| 15 | + return "Unsupported parameter"; | ||
| 16 | + case AACENC_INVALID_CONFIG: | ||
| 17 | + return "Invalid config"; | ||
| 18 | + case AACENC_INIT_ERROR: | ||
| 19 | + return "Initialization error"; | ||
| 20 | + case AACENC_INIT_AAC_ERROR: | ||
| 21 | + return "AAC library initialization error"; | ||
| 22 | + case AACENC_INIT_SBR_ERROR: | ||
| 23 | + return "SBR library initialization error"; | ||
| 24 | + case AACENC_INIT_TP_ERROR: | ||
| 25 | + return "Transport library initialization error"; | ||
| 26 | + case AACENC_INIT_META_ERROR: | ||
| 27 | + return "Metadata library initialization error"; | ||
| 28 | + case AACENC_ENCODE_ERROR: | ||
| 29 | + return "Encoding error"; | ||
| 30 | + case AACENC_ENCODE_EOF: | ||
| 31 | + return "End of file"; | ||
| 32 | + default: | ||
| 33 | + return "Unknown error"; | ||
| 34 | + } | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +typedef struct { | ||
| 38 | + HANDLE_AACENCODER handle; | ||
| 39 | + int afterburner; | ||
| 40 | + int eld_sbr; | ||
| 41 | + int signaling; | ||
| 42 | + int latm; | ||
| 43 | + int header_period; | ||
| 44 | + int vbr; | ||
| 45 | + uint8_t buf[2048]; | ||
| 46 | + int data_len; | ||
| 47 | +} handle_aec_aac_t; | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +static int open_codec_aac(tc_audio_opt* opt) { | ||
| 51 | + handle_aec_aac_t* s = (handle_aec_aac_t*)calloc(1, sizeof(handle_aec_aac_t)); | ||
| 52 | + opt->handle = s; | ||
| 53 | + AACENC_ERROR err = AACENC_OK; | ||
| 54 | + AACENC_InfoStruct info = { 0 }; | ||
| 55 | + CHANNEL_MODE mode; | ||
| 56 | + int sce = 0, cpe = 0; | ||
| 57 | + do{ | ||
| 58 | + if ((err = aacEncOpen(&s->handle, 0, opt->channels)) != AACENC_OK) { | ||
| 59 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to open the encoder.\n"); | ||
| 60 | + break; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + int aot; | ||
| 64 | + if(opt->audio_profile == 0) { | ||
| 65 | + aot = 2; //LC-AAC | ||
| 66 | + }else { | ||
| 67 | + aot = 5; //HE-AAC | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + //set audio object type | ||
| 71 | + if ((err = aacEncoder_SetParam(s->handle, AACENC_AOT, aot)) != AACENC_OK) { | ||
| 72 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to set the AOT %d: %s\n",aot, aac_get_error(err)); | ||
| 73 | + break; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + //set sample rate | ||
| 77 | + if ((err = aacEncoder_SetParam(s->handle, AACENC_SAMPLERATE, opt->sample_rate)) != AACENC_OK) { | ||
| 78 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to set the sample rate %d: %s\n",opt->sample_rate, aac_get_error(err)); | ||
| 79 | + break; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + switch (opt->channels) { | ||
| 83 | + case 1: mode = MODE_1; sce = 1; cpe = 0; break; | ||
| 84 | + case 2: mode = MODE_2; sce = 0; cpe = 1; break; | ||
| 85 | + default:mode = MODE_1; sce = 1; cpe = 0; break; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + if ((err = aacEncoder_SetParam(s->handle, AACENC_CHANNELMODE, mode)) != AACENC_OK) { | ||
| 89 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to set channel mode %d: %s\n", mode, aac_get_error(err)); | ||
| 90 | + break; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + if ((err = aacEncoder_SetParam(s->handle, AACENC_CHANNELORDER, 1)) != AACENC_OK) { | ||
| 94 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to set channel order %d: %s\n", mode, aac_get_error(err)); | ||
| 95 | + break; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + if ((err = aacEncoder_SetParam(s->handle, AACENC_BITRATE, opt->audio_bitrate)) != AACENC_OK) { | ||
| 99 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to set the bitrate %d: %s\n", opt->audio_bitrate, aac_get_error(err)); | ||
| 100 | + break; | ||
| 101 | + } | ||
| 102 | + if (aacEncoder_SetParam(s->handle, AACENC_TRANSMUX, 0) != AACENC_OK) { | ||
| 103 | + tc_log(LOG_LEVEL_ERROR, "Unable to set the ADTS transmux\n"); | ||
| 104 | + break; | ||
| 105 | + } | ||
| 106 | + if ((err = aacEncoder_SetParam(s->handle, AACENC_SIGNALING_MODE, 2)) != AACENC_OK) { | ||
| 107 | + tc_log(LOG_LEVEL_ERROR, "Unable to set signaling mode %d: %s\n",2, aac_get_error(err)); | ||
| 108 | + break; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + if (aacEncEncode(s->handle, NULL, NULL, NULL, NULL) != AACENC_OK) { | ||
| 112 | + tc_log(LOG_LEVEL_ERROR, "Unable to initialize the encoder\n"); | ||
| 113 | + return 1; | ||
| 114 | + } | ||
| 115 | + if (aacEncInfo(s->handle, &info) != AACENC_OK) { | ||
| 116 | + tc_log(LOG_LEVEL_ERROR, "Unable to get the encoder info\n"); | ||
| 117 | + return 1; | ||
| 118 | + } | ||
| 119 | + opt->extradata = (uint8_t *)malloc(info.confSize); | ||
| 120 | + opt->extradata_size = info.confSize; | ||
| 121 | + memcpy(opt->extradata, info.confBuf, info.confSize); | ||
| 122 | + | ||
| 123 | + }while (0); | ||
| 124 | + | ||
| 125 | + if( err != AACENC_OK) { | ||
| 126 | + aacEncClose(&s->handle); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + return 0; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | + | ||
| 133 | +static int encode_frame_aac(tc_audio_opt* opt, uint8_t* inData, uint8_t* inOutData, uint32_t* inOutDataSize) { | ||
| 134 | + handle_aec_aac_t* s = (handle_aec_aac_t*)opt->handle; | ||
| 135 | + | ||
| 136 | + AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 }; | ||
| 137 | + AACENC_InArgs in_args = { 0 }; | ||
| 138 | + AACENC_OutArgs out_args = { 0 }; | ||
| 139 | + int in_identifier = IN_AUDIO_DATA; | ||
| 140 | + int in_size, in_elem_size; | ||
| 141 | + int out_identifier = OUT_BITSTREAM_DATA; | ||
| 142 | + int out_size, out_elem_size; | ||
| 143 | + void *in_ptr, *out_ptr; | ||
| 144 | + AACENC_ERROR err; | ||
| 145 | + | ||
| 146 | + if (s->data_len + opt->buffer_size < 2048){ | ||
| 147 | + memcpy(s->buf + s->data_len, inData, opt->buffer_size); | ||
| 148 | + s->data_len += opt->buffer_size; | ||
| 149 | + *inOutDataSize = 0; | ||
| 150 | + return 0; | ||
| 151 | + } | ||
| 152 | + else{ | ||
| 153 | + memcpy(s->buf + s->data_len, inData, 2048 - s->data_len); | ||
| 154 | + | ||
| 155 | + in_ptr = s->buf; | ||
| 156 | + in_size = 2048; | ||
| 157 | + in_elem_size = 2; | ||
| 158 | + | ||
| 159 | + in_args.numInSamples = opt->frame_size; | ||
| 160 | + in_buf.numBufs = 1; | ||
| 161 | + in_buf.bufs = &in_ptr; | ||
| 162 | + in_buf.bufferIdentifiers = &in_identifier; | ||
| 163 | + in_buf.bufSizes = &in_size; | ||
| 164 | + in_buf.bufElSizes = &in_elem_size; | ||
| 165 | + | ||
| 166 | + out_ptr = inOutData; | ||
| 167 | + out_size = *inOutDataSize; | ||
| 168 | + out_elem_size = 1; | ||
| 169 | + out_buf.numBufs = 1; | ||
| 170 | + out_buf.bufs = &out_ptr; | ||
| 171 | + out_buf.bufferIdentifiers = &out_identifier; | ||
| 172 | + out_buf.bufSizes = &out_size; | ||
| 173 | + out_buf.bufElSizes = &out_elem_size; | ||
| 174 | + | ||
| 175 | + if ((err = aacEncEncode(s->handle, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) { | ||
| 176 | + tc_log(LOG_LEVEL_ERROR, "[aac] Unable to encode frame: %s\n", aac_get_error(err)); | ||
| 177 | + return -1; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + *inOutDataSize = out_args.numOutBytes; | ||
| 181 | + memcpy(s->buf, inData + 2048 - s->data_len, opt->buffer_size -( 2048 - s->data_len)); | ||
| 182 | + s->data_len = opt->buffer_size - (2048 - s->data_len); | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + return 0; | ||
| 186 | +} | ||
| 187 | + | ||
| 188 | +static int close_codec_aac(tc_audio_opt* opt) { | ||
| 189 | + handle_aec_aac_t* s = (handle_aec_aac_t*)opt->handle; | ||
| 190 | + if (s->handle) { | ||
| 191 | + aacEncClose(&s->handle); | ||
| 192 | + } | ||
| 193 | + freep(opt->extradata); | ||
| 194 | + freep(opt->handle); | ||
| 195 | + return 0; | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | + | ||
| 199 | +const tc_av_codec_t aec_aac = { | ||
| 200 | + 10, | ||
| 201 | + "aec_aac", | ||
| 202 | + open_codec_aac, | ||
| 203 | + NULL, | ||
| 204 | + encode_frame_aac, | ||
| 205 | + close_codec_aac | ||
| 206 | +}; |
trunk/src/transcode/srs_tc_av_codec.hpp
0 → 100644
| 1 | +#ifndef TC_AV_CODEC_H | ||
| 2 | +#define TC_AV_CODEC_H | ||
| 3 | + | ||
| 4 | +#include <stdint.h> | ||
| 5 | +#include <stdio.h> | ||
| 6 | +#include <stdlib.h> | ||
| 7 | +#include <string.h> | ||
| 8 | + | ||
| 9 | +#define MAX_EXTRA 3 | ||
| 10 | + | ||
| 11 | +typedef void* handle_t; | ||
| 12 | + | ||
| 13 | +typedef struct { | ||
| 14 | + int sample_rate; | ||
| 15 | + int channels; | ||
| 16 | + int frame_size; | ||
| 17 | + int buffer_size; | ||
| 18 | + int audio_profile; | ||
| 19 | + int audio_bitrate; | ||
| 20 | + | ||
| 21 | + handle_t handle; | ||
| 22 | + | ||
| 23 | + uint32_t extradata_size; | ||
| 24 | + uint8_t* extradata; | ||
| 25 | + | ||
| 26 | +}tc_audio_opt; | ||
| 27 | + | ||
| 28 | +typedef struct { | ||
| 29 | + int codec_id; | ||
| 30 | + | ||
| 31 | + const char* codec_name; | ||
| 32 | + | ||
| 33 | + int (*open_codec)(tc_audio_opt* opt); | ||
| 34 | + | ||
| 35 | + int (*decode_frame)(tc_audio_opt* opt, uint8_t* inData, uint32_t inDataSize, uint8_t* outData); | ||
| 36 | + | ||
| 37 | + int (*encode_frame)(tc_audio_opt* opt, uint8_t* inData, uint8_t* inoutData, uint32_t* inoutDataSize); | ||
| 38 | + | ||
| 39 | + int (*close_codec)(tc_audio_opt* opt); | ||
| 40 | + | ||
| 41 | +}tc_av_codec_t; | ||
| 42 | + | ||
| 43 | + | ||
| 44 | +extern const tc_av_codec_t adc_aac; | ||
| 45 | +extern const tc_av_codec_t aec_aac; | ||
| 46 | + | ||
| 47 | +extern const tc_av_codec_t adc_spx; | ||
| 48 | + | ||
| 49 | +#define freep(x) if(x){ free(x); x = NULL;} | ||
| 50 | +#endif /* tc_av_codec_h */ |
trunk/src/transcode/srs_tc_common.cpp
0 → 100644
| 1 | +#include "srs_tc_common.hpp" | ||
| 2 | +#include <stdarg.h> | ||
| 3 | +#include <srs_kernel_log.hpp> | ||
| 4 | + | ||
| 5 | +void tc_log(int log_level, const char *format, ...) | ||
| 6 | +{ | ||
| 7 | + va_list args; | ||
| 8 | + va_start(args, format); | ||
| 9 | + | ||
| 10 | + if (log_level == LOG_LEVEL_INFO){ | ||
| 11 | + srs_info(format, args); | ||
| 12 | + } | ||
| 13 | + else if (log_level == LOG_LEVEL_WARN){ | ||
| 14 | + srs_warn(format, args); | ||
| 15 | + } | ||
| 16 | + else if (log_level == LOG_LEVEL_ERROR){ | ||
| 17 | + srs_error(format, args); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + va_end(args); | ||
| 21 | +} |
-
请 注册 或 登录 后发表评论