diff --git a/trunk/research/librtmp/srs_detect_rtmp.c b/trunk/research/librtmp/srs_detect_rtmp.c index 155d28bd0..84d18cc34 100644 --- a/trunk/research/librtmp/srs_detect_rtmp.c +++ b/trunk/research/librtmp/srs_detect_rtmp.c @@ -35,7 +35,7 @@ int main(int argc, char** argv) srs_rtmp_t rtmp; // time - int64_t time_startup = srs_utils_get_time_ms(); + int64_t time_startup = srs_utils_time_ms(); int64_t time_dns_resolve = 0; int64_t time_socket_connect = 0; int64_t time_play_stream = 0; @@ -95,14 +95,14 @@ int main(int argc, char** argv) goto rtmp_destroy; } srs_human_trace("dns resolve success"); - time_dns_resolve = srs_utils_get_time_ms(); + time_dns_resolve = srs_utils_time_ms(); if ((ret = __srs_rtmp_connect_server(rtmp)) != 0) { srs_human_trace("socket connect failed. ret=%d", ret); goto rtmp_destroy; } srs_human_trace("socket connect success"); - time_socket_connect = srs_utils_get_time_ms(); + time_socket_connect = srs_utils_time_ms(); if ((ret = __srs_rtmp_do_simple_handshake(rtmp)) != 0) { srs_human_trace("do simple handshake failed. ret=%d", ret); @@ -121,7 +121,7 @@ int main(int argc, char** argv) goto rtmp_destroy; } srs_human_trace("play stream success"); - time_play_stream = srs_utils_get_time_ms(); + time_play_stream = srs_utils_time_ms(); for (;;) { if ((ret = srs_rtmp_read_packet(rtmp, &type, ×tamp, &data, &size)) != 0) { @@ -133,7 +133,7 @@ int main(int argc, char** argv) if (SRS_RTMP_TYPE_VIDEO == type || SRS_RTMP_TYPE_AUDIO == type) { if (time_first_packet <= 0) { - time_first_packet = srs_utils_get_time_ms(); + time_first_packet = srs_utils_time_ms(); } if (basetime <= 0) { basetime = timestamp; @@ -142,7 +142,7 @@ int main(int argc, char** argv) free(data); - if (srs_utils_get_time_ms() - time_startup > timeout * 1000) { + if (srs_utils_time_ms() - time_startup > timeout * 1000) { srs_human_trace("timeout, terminate."); goto rtmp_destroy; } @@ -154,11 +154,11 @@ int main(int argc, char** argv) } rtmp_destroy: - bytes_nsend = srs_utils_get_send_bytes(rtmp); - bytes_nrecv = srs_utils_get_recv_bytes(rtmp); + bytes_nsend = srs_utils_send_bytes(rtmp); + bytes_nrecv = srs_utils_recv_bytes(rtmp); srs_rtmp_destroy(rtmp); - time_cleanup = srs_utils_get_time_ms(); + time_cleanup = srs_utils_time_ms(); time_duration = (int)(time_cleanup - time_startup); // print result to stderr. diff --git a/trunk/research/librtmp/srs_ingest_flv.c b/trunk/research/librtmp/srs_ingest_flv.c index 8b21170f6..55466af4b 100644 --- a/trunk/research/librtmp/srs_ingest_flv.c +++ b/trunk/research/librtmp/srs_ingest_flv.c @@ -48,7 +48,7 @@ int main(int argc, char** argv) int ret = 0; // main function - tools_main_entrance_startup_time = srs_utils_get_time_ms(); + tools_main_entrance_startup_time = srs_utils_time_ms(); // user option parse index. int opt = 0; @@ -215,7 +215,7 @@ int connect_oc(srs_rtmp_t ortmp) int64_t re_create() { // if not very precise, we can directly use this as re. - int64_t re = srs_utils_get_time_ms(); + int64_t re = srs_utils_time_ms(); // use the starttime to get the deviation int64_t deviation = re - tools_main_entrance_startup_time; @@ -236,7 +236,7 @@ int64_t re_create() void re_update(int64_t re, int32_t starttime, u_int32_t time) { // send by pulse algorithm. - int64_t now = srs_utils_get_time_ms(); + int64_t now = srs_utils_time_ms(); int64_t diff = time - starttime - (now -re); if (diff > RE_PULSE_MS) { usleep(diff * 1000); @@ -246,7 +246,7 @@ void re_cleanup(int64_t re, int32_t starttime, u_int32_t time) { // for the last pulse, always sleep. // for the virtual live encoder long time publishing. - int64_t now = srs_utils_get_time_ms(); + int64_t now = srs_utils_time_ms(); int64_t diff = time - starttime - (now -re); if (diff > 0) { srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms", diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 591faf819..362963d57 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -1712,20 +1712,20 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) obj->append(any); } -int64_t srs_utils_get_time_ms() +int64_t srs_utils_time_ms() { srs_update_system_time_ms(); return srs_get_system_time_ms(); } -int64_t srs_utils_get_send_bytes(srs_rtmp_t rtmp) +int64_t srs_utils_send_bytes(srs_rtmp_t rtmp) { srs_assert(rtmp != NULL); Context* context = (Context*)rtmp; return context->rtmp->get_send_bytes(); } -int64_t srs_utils_get_recv_bytes(srs_rtmp_t rtmp) +int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp) { srs_assert(rtmp != NULL); Context* context = (Context*)rtmp; @@ -1773,7 +1773,7 @@ int srs_utils_parse_timestamp( return ret; } -char srs_utils_get_flv_video_codec_id(char* data, int size) +char srs_utils_flv_video_codec_id(char* data, int size) { if (size < 1) { return 0; @@ -1785,7 +1785,7 @@ char srs_utils_get_flv_video_codec_id(char* data, int size) return codec_id; } -char srs_utils_get_flv_video_avc_packet_type(char* data, int size) +char srs_utils_flv_video_avc_packet_type(char* data, int size) { if (size < 2) { return -1; @@ -1804,7 +1804,7 @@ char srs_utils_get_flv_video_avc_packet_type(char* data, int size) return avc_packet_type; } -char srs_utils_get_flv_video_frame_type(char* data, int size) +char srs_utils_flv_video_frame_type(char* data, int size) { if (size < 1) { return -1; @@ -1823,6 +1823,85 @@ char srs_utils_get_flv_video_frame_type(char* data, int size) return frame_type; } +char srs_utils_flv_audio_sound_format(char* data, int size) +{ + if (size < 1) { + return -1; + } + + u_int8_t sound_format = data[0]; + sound_format = (sound_format >> 4) & 0x0f; + if (sound_format > 15 || sound_format == 12 || sound_format == 13) { + return -1; + } + + return sound_format; +} + +char srs_utils_flv_audio_sound_rate(char* data, int size) +{ + if (size < 1) { + return -1; + } + + u_int8_t sound_rate = data[0]; + sound_rate = (sound_rate >> 2) & 0x03; + if (sound_rate > 3) { + return -1; + } + + return sound_rate; +} + +char srs_utils_flv_audio_sound_size(char* data, int size) +{ + if (size < 1) { + return -1; + } + + u_int8_t sound_size = data[0]; + sound_size = (sound_size >> 1) & 0x01; + if (sound_size > 1) { + return -1; + } + + return sound_size; +} + +char srs_utils_flv_audio_sound_type(char* data, int size) +{ + if (size < 1) { + return -1; + } + + u_int8_t sound_type = data[0]; + sound_type = sound_type & 0x01; + if (sound_type > 1) { + return -1; + } + + return sound_type; +} + +char srs_utils_flv_audio_aac_packet_type(char* data, int size) +{ + if (size < 2) { + return -1; + } + + if (srs_utils_flv_audio_sound_format(data, size) != 10) { + return -1; + } + + u_int8_t aac_packet_type = data[1]; + aac_packet_type = aac_packet_type; + if (aac_packet_type > 1) { + return -1; + } + + return aac_packet_type; +} + char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize) { if (!amf0) { @@ -1876,7 +1955,7 @@ const char* srs_human_flv_video_codec_id2string(char codec_id) const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type) { - static const char* sps_pps = "SpsPps"; + static const char* sps_pps = "SH"; static const char* nalu = "Nalu"; static const char* sps_pps_end = "SpsPpsEnd"; static const char* unknown = "Unknown"; @@ -1912,6 +1991,109 @@ const char* srs_human_flv_video_frame_type2string(char frame_type) return unknown; } +const char* srs_human_flv_audio_sound_format2string(char sound_format) +{ + static const char* linear_pcm = "LinearPCM"; + static const char* ad_pcm = "ADPCM"; + static const char* mp3 = "MP3"; + static const char* linear_pcm_le = "LinearPCMLe"; + static const char* nellymoser_16khz = "NellymoserKHz16"; + static const char* nellymoser_8khz = "NellymoserKHz8"; + static const char* nellymoser = "Nellymoser"; + static const char* g711_a_pcm = "G711APCM"; + static const char* g711_mu_pcm = "G711MuPCM"; + static const char* reserved = "Reserved"; + static const char* aac = "AAC"; + static const char* speex = "Speex"; + static const char* mp3_8khz = "MP3KHz8"; + static const char* device_specific = "DeviceSpecific"; + static const char* unknown = "Unknown"; + + switch (sound_format) { + case 0: return linear_pcm; + case 1: return ad_pcm; + case 2: return mp3; + case 3: return linear_pcm_le; + case 4: return nellymoser_16khz; + case 5: return nellymoser_8khz; + case 6: return nellymoser; + case 7: return g711_a_pcm; + case 8: return g711_mu_pcm; + case 9: return reserved; + case 10: return aac; + case 11: return speex; + case 14: return mp3_8khz; + case 15: return device_specific; + default: return unknown; + } + + return unknown; +} + +const char* srs_human_flv_audio_sound_rate2string(char sound_rate) +{ + static const char* khz_5_5 = "5.5KHz"; + static const char* khz_11 = "11KHz"; + static const char* khz_22 = "22KHz"; + static const char* khz_44 = "44KHz"; + static const char* unknown = "Unknown"; + + switch (sound_rate) { + case 0: return khz_5_5; + case 1: return khz_11; + case 2: return khz_22; + case 3: return khz_44; + default: return unknown; + } + + return unknown; +} + +const char* srs_human_flv_audio_sound_size2string(char sound_size) +{ + static const char* bit_8 = "8bit"; + static const char* bit_16 = "16bit"; + static const char* unknown = "Unknown"; + + switch (sound_size) { + case 0: return bit_8; + case 1: return bit_16; + default: return unknown; + } + + return unknown; +} + +const char* srs_human_flv_audio_sound_type2string(char sound_type) +{ + static const char* mono = "Mono"; + static const char* stereo = "Stereo"; + static const char* unknown = "Unknown"; + + switch (sound_type) { + case 0: return mono; + case 1: return stereo; + default: return unknown; + } + + return unknown; +} + +const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type) +{ + static const char* sps_pps = "SH"; + static const char* raw = "Raw"; + static const char* unknown = "Unknown"; + + switch (aac_packet_type) { + case 0: return sps_pps; + case 1: return raw; + default: return unknown; + } + + return unknown; +} + int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size) { int ret = ERROR_SUCCESS; @@ -1924,13 +2106,19 @@ int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int if (type == SRS_RTMP_TYPE_VIDEO) { srs_human_trace("Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s)", srs_human_flv_tag_type2string(type), timestamp, pts, size, - srs_human_flv_video_codec_id2string(srs_utils_get_flv_video_codec_id(data, size)), - srs_human_flv_video_avc_packet_type2string(srs_utils_get_flv_video_avc_packet_type(data, size)), - srs_human_flv_video_frame_type2string(srs_utils_get_flv_video_frame_type(data, size)) + srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)), + srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)), + srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size)) ); } else if (type == SRS_RTMP_TYPE_AUDIO) { - srs_human_trace("Audio packet type=%s, dts=%d, pts=%d, size=%d", - srs_human_flv_tag_type2string(type), timestamp, pts, size); + srs_human_trace("Audio packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s,%s,%s)", + srs_human_flv_tag_type2string(type), timestamp, pts, size, + srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)), + srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)), + srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)), + srs_human_flv_audio_sound_type2string(srs_utils_flv_audio_sound_type(data, size)), + srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size)) + ); } else if (type == SRS_RTMP_TYPE_SCRIPT) { srs_human_verbose("Data packet type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size); diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index 8bed20596..371a2ca83 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -592,17 +592,17 @@ extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value); * get the current system time in ms. * use gettimeofday() to get system time. */ -extern int64_t srs_utils_get_time_ms(); +extern int64_t srs_utils_time_ms(); /** * get the send bytes. */ -extern int64_t srs_utils_get_send_bytes(srs_rtmp_t rtmp); +extern int64_t srs_utils_send_bytes(srs_rtmp_t rtmp); /** * get the recv bytes. */ -extern int64_t srs_utils_get_recv_bytes(srs_rtmp_t rtmp); +extern int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp); /** * parse the dts and pts by time in header and data in tag, @@ -635,7 +635,7 @@ extern int srs_utils_parse_timestamp( * 7 = AVC * @return the code id. 0 for error. */ -extern char srs_utils_get_flv_video_codec_id(char* data, int size); +extern char srs_utils_flv_video_codec_id(char* data, int size); /** * get the AVCPacketType of video tag. @@ -646,7 +646,7 @@ extern char srs_utils_get_flv_video_codec_id(char* data, int size); * not required or supported) * @return the avc packet type. -1(0xff) for error. */ -extern char srs_utils_get_flv_video_avc_packet_type(char* data, int size); +extern char srs_utils_flv_video_avc_packet_type(char* data, int size); /** * get the FrameType of video tag. @@ -658,7 +658,71 @@ extern char srs_utils_get_flv_video_avc_packet_type(char* data, int size); * 5 = video info/command frame * @return the frame type. 0 for error. */ -extern char srs_utils_get_flv_video_frame_type(char* data, int size); +extern char srs_utils_flv_video_frame_type(char* data, int size); + +/** +* get the SoundFormat of audio tag. +* Format of SoundData. The following values are defined: +* 0 = Linear PCM, platform endian +* 1 = ADPCM +* 2 = MP3 +* 3 = Linear PCM, little endian +* 4 = Nellymoser 16 kHz mono +* 5 = Nellymoser 8 kHz mono +* 6 = Nellymoser +* 7 = G.711 A-law logarithmic PCM +* 8 = G.711 mu-law logarithmic PCM +* 9 = reserved +* 10 = AAC +* 11 = Speex +* 14 = MP3 8 kHz +* 15 = Device-specific sound +* Formats 7, 8, 14, and 15 are reserved. +* AAC is supported in Flash Player 9,0,115,0 and higher. +* Speex is supported in Flash Player 10 and higher. +* @return the sound format. -1(0xff) for error. +*/ +extern char srs_utils_flv_audio_sound_format(char* data, int size); + +/** +* get the SoundRate of audio tag. +* Sampling rate. The following values are defined: +* 0 = 5.5 kHz +* 1 = 11 kHz +* 2 = 22 kHz +* 3 = 44 kHz +* @return the sound rate. -1(0xff) for error. +*/ +extern char srs_utils_flv_audio_sound_rate(char* data, int size); + +/** +* get the SoundSize of audio tag. +* Size of each audio sample. This parameter only pertains to +* uncompressed formats. Compressed formats always decode +* to 16 bits internally. +* 0 = 8-bit samples +* 1 = 16-bit samples +* @return the sound size. -1(0xff) for error. +*/ +extern char srs_utils_flv_audio_sound_size(char* data, int size); + +/** +* get the SoundType of audio tag. +* Mono or stereo sound +* 0 = Mono sound +* 1 = Stereo sound +* @return the sound type. -1(0xff) for error. +*/ +extern char srs_utils_flv_audio_sound_type(char* data, int size); + +/** +* get the AACPacketType of audio tag. +* The following values are defined: +* 0 = AAC sequence header +* 1 = AAC raw +* @return the aac packet type. -1(0xff) for error. +*/ +extern char srs_utils_flv_audio_aac_packet_type(char* data, int size); /************************************************************* ************************************************************** @@ -699,7 +763,7 @@ extern const char* srs_human_flv_video_codec_id2string(char codec_id); /** * get the avc packet type string. -* SpsPps = AVC sequence header +* SH = AVC sequence header * Nalu = AVC NALU * SpsPpsEnd = AVC end of sequence * otherwise, "Unknown" @@ -721,6 +785,77 @@ extern const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_ty */ extern const char* srs_human_flv_video_frame_type2string(char frame_type); +/** +* get the SoundFormat string. +* Format of SoundData. The following values are defined: +* LinearPCM = Linear PCM, platform endian +* ADPCM = ADPCM +* MP3 = MP3 +* LinearPCMLe = Linear PCM, little endian +* NellymoserKHz16 = Nellymoser 16 kHz mono +* NellymoserKHz8 = Nellymoser 8 kHz mono +* Nellymoser = Nellymoser +* G711APCM = G.711 A-law logarithmic PCM +* G711MuPCM = G.711 mu-law logarithmic PCM +* Reserved = reserved +* AAC = AAC +* Speex = Speex +* MP3KHz8 = MP3 8 kHz +* DeviceSpecific = Device-specific sound +* otherwise, "Unknown" +* @remark user never free the return char*, +* it's static shared const string. +*/ +extern const char* srs_human_flv_audio_sound_format2string(char sound_format); + +/** +* get the SoundRate of audio tag. +* Sampling rate. The following values are defined: +* 5.5KHz = 5.5 kHz +* 11KHz = 11 kHz +* 22KHz = 22 kHz +* 44KHz = 44 kHz +* otherwise, "Unknown" +* @remark user never free the return char*, +* it's static shared const string. +*/ +extern const char* srs_human_flv_audio_sound_rate2string(char sound_rate); + +/** +* get the SoundSize of audio tag. +* Size of each audio sample. This parameter only pertains to +* uncompressed formats. Compressed formats always decode +* to 16 bits internally. +* 8bit = 8-bit samples +* 16bit = 16-bit samples +* otherwise, "Unknown" +* @remark user never free the return char*, +* it's static shared const string. +*/ +extern const char* srs_human_flv_audio_sound_size2string(char sound_size); + +/** +* get the SoundType of audio tag. +* Mono or stereo sound +* Mono = Mono sound +* Stereo = Stereo sound +* otherwise, "Unknown" +* @remark user never free the return char*, +* it's static shared const string. +*/ +extern const char* srs_human_flv_audio_sound_type2string(char sound_type); + +/** +* get the AACPacketType of audio tag. +* The following values are defined: +* SH = AAC sequence header +* Raw = AAC raw +* otherwise, "Unknown" +* @remark user never free the return char*, +* it's static shared const string. +*/ +extern const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type); + /** * print the rtmp packet, use srs_human_trace/srs_human_verbose for packet, * and use srs_human_raw for script data body.