diff --git a/trunk/research/librtmp/Makefile b/trunk/research/librtmp/Makefile index 58b0455e2..ec2e30ca1 100755 --- a/trunk/research/librtmp/Makefile +++ b/trunk/research/librtmp/Makefile @@ -5,11 +5,12 @@ GCC = gcc default: help help: - @echo "Usage: make |||||||||" + @echo "Usage: make ||||||||||" @echo " help display this help" @echo " clean cleanup build" - @echo " ssl srs_publish_ssl, srs_play_ssl, srs_ingest_flv, srs_ingest_rtmp" - @echo " nossl srs_publish_nossl, srs_play_nossl, srs_ingest_flv, srs_ingest_rtmp" + @echo " ssl srs_flv_parser, srs_publish_ssl, srs_play_ssl, srs_ingest_flv, srs_ingest_rtmp" + @echo " nossl srs_flv_parser, srs_publish_nossl, srs_play_nossl, srs_ingest_flv, srs_ingest_rtmp" + @echo " srs_flv_parser parse flv file, print detail info." @echo " srs_publish_nossl publish program using srs-librtmp, without ssl(simple handshake)" @echo " srs_play_nossl play program using srs-librtmp, without ssl(simple handshake)" @echo " srs_publish_ssl publish program using srs-librtmp, with ssl(complex handshake)" @@ -26,7 +27,7 @@ help: @echo "Remark: before make this sample, user must make the srs, with/without ssl" clean: - @rm -f srs_publish_nossl srs_play_nossl srs_publish_ssl srs_play_ssl srs_ingest_flv_ssl srs_ingest_rtmp_ssl srs_ingest_flv_nossl srs_ingest_rtmp_nossl + @rm -f srs_flv_parser srs_publish_nossl srs_play_nossl srs_publish_ssl srs_play_ssl srs_ingest_flv_ssl srs_ingest_rtmp_ssl srs_ingest_flv_nossl srs_ingest_rtmp_nossl # srs library root SRS_OBJS = ../../objs @@ -51,6 +52,9 @@ ifeq ($(GCC), mipsel-openwrt-linux-gcc) EXTRA_CXX_FLAG = -g -O0 -ldl -lstdc++ -lgcc_eh endif +srs_flv_parser_nossl: srs_flv_parser.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) + $(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(EXTRA_CXX_FLAG) -o srs_flv_parser_nossl + srs_publish_nossl: srs_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(EXTRA_CXX_FLAG) -o srs_publish_nossl @@ -63,6 +67,9 @@ srs_ingest_flv_nossl: srs_ingest_flv.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(S srs_ingest_rtmp_nossl: srs_ingest_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(GCC) srs_ingest_rtmp.c $(SRS_LIBRTMP_L) $(EXTRA_CXX_FLAG) -o srs_ingest_rtmp_nossl +srs_flv_parser_ssl: srs_flv_parser.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) + $(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_flv_parser_ssl + srs_publish_ssl: srs_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_publish_ssl @@ -76,5 +83,5 @@ srs_ingest_rtmp_ssl: srs_ingest_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(S $(GCC) srs_ingest_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_ingest_rtmp_ssl # alias for publish/play with/without ssl -ssl: srs_publish_ssl srs_play_ssl srs_ingest_flv_ssl srs_ingest_rtmp_ssl -nossl: srs_publish_nossl srs_play_nossl srs_ingest_flv_nossl srs_ingest_rtmp_nossl +ssl: srs_flv_parser_ssl srs_publish_ssl srs_play_ssl srs_ingest_flv_ssl srs_ingest_rtmp_ssl +nossl: srs_flv_parser_nossl srs_publish_nossl srs_play_nossl srs_ingest_flv_nossl srs_ingest_rtmp_nossl diff --git a/trunk/research/librtmp/srs_flv_codec.h b/trunk/research/librtmp/srs_flv_codec.h new file mode 100644 index 000000000..838df5034 --- /dev/null +++ b/trunk/research/librtmp/srs_flv_codec.h @@ -0,0 +1,147 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_RESEARH_FLV_CODEC_HPP +#define SRS_RESEARH_FLV_CODEC_HPP + +/* +#include "srs_flv_codec.h" +*/ + +#include +#include +#include +#include + +#define ERROR_FLV_CODEC_EOF 100 + +int open_flv_file(char* in_flv_file) +{ + return open(in_flv_file, O_RDONLY); +} + +void close_flv_file(int fd) +{ + if (fd > 0) { + close(fd); + } +} + +int flv_open_ic(int flv_fd) +{ + int ret = 0; + + char h[13]; // 9+4 + + if (read(flv_fd, h, sizeof(h)) != sizeof(h)) { + ret = -1; + trace("read flv header failed. ret=%d", ret); + return ret; + } + + if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { + ret = -1; + trace("input is not a flv file. ret=%d", ret); + return ret; + } + + return ret; +} + +int flv_read_packet(int flv_fd, int* type, u_int32_t* timestamp, char** data, int* size) +{ + int ret = 0; + + char th[11]; // tag header + char ts[4]; // tag size + + int32_t data_size = 0; + u_int32_t time = 0; + + char* pp; + + // read tag header + if ((ret = read(flv_fd, th, sizeof(th))) != sizeof(th)) { + if (ret == 0) { + return ERROR_FLV_CODEC_EOF; + } + ret = -1; + trace("read flv tag header failed. ret=%d", ret); + return ret; + } + + // Reserved UB [2] + // Filter UB [1] + // TagType UB [5] + *type = (int)(th[0] & 0x1F); + + // DataSize UI24 + pp = (char*)&data_size; + pp[2] = th[1]; + pp[1] = th[2]; + pp[0] = th[3]; + + // Timestamp UI24 + pp = (char*)&time; + pp[2] = th[4]; + pp[1] = th[5]; + pp[0] = th[6]; + + // TimestampExtended UI8 + pp[3] = th[7]; + + *timestamp = time; + + // check data size. + if (data_size <= 0) { + ret = -1; + trace("invalid data size. size=%d, ret=%d", data_size, ret); + return ret; + } + + // read tag data. + *size = data_size; + *data = (char*)malloc(data_size); + if ((ret = read(flv_fd, *data, data_size)) != data_size) { + if (ret == 0) { + return ERROR_FLV_CODEC_EOF; + } + ret = -1; + trace("read flv tag data failed. size=%d, ret=%d", data_size, ret); + return ret; + } + + // ignore 4bytes tag size. + if ((ret = read(flv_fd, ts, sizeof(ts))) != sizeof(ts)) { + if (ret == 0) { + return ERROR_FLV_CODEC_EOF; + } + ret = -1; + trace("read flv tag size failed. ret=%d", ret); + return ret; + } + + return 0; +} + +#endif diff --git a/trunk/research/librtmp/srs_ingest_flv.c b/trunk/research/librtmp/srs_ingest_flv.c index 207f0aa9c..ab3e87838 100644 --- a/trunk/research/librtmp/srs_ingest_flv.c +++ b/trunk/research/librtmp/srs_ingest_flv.c @@ -34,15 +34,11 @@ gcc srs_ingest_flv.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest_ #include "../../objs/include/srs_librtmp.h" #include "srs_research_public.h" +#include "srs_flv_codec.h" int proxy(int flv_fd, srs_rtmp_t ortmp); int connect_oc(srs_rtmp_t ortmp); -int open_flv_file(char* in_flv_file); -void close_flv_file(int flv_fd); -int flv_open_ic(int flv_fd); -int flv_read_packet(int flv_fd, int* type, u_int32_t* timestamp, char** data, int* size); - #define RE_PULSE_MS 300 int64_t re_create(); void re_update(int64_t re, u_int32_t time); @@ -234,103 +230,3 @@ void re_cleanup(int64_t re, u_int32_t time) usleep(diff * 1000); } } - -int open_flv_file(char* in_flv_file) -{ - return open(in_flv_file, O_RDONLY); -} - -void close_flv_file(int fd) -{ - if (fd > 0) { - close(fd); - } -} - -int flv_open_ic(int flv_fd) -{ - int ret = 0; - - char h[13]; // 9+4 - - if (read(flv_fd, h, sizeof(h)) != sizeof(h)) { - ret = -1; - trace("read flv header failed. ret=%d", ret); - return ret; - } - - if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { - ret = -1; - trace("input is not a flv file. ret=%d", ret); - return ret; - } - - return ret; -} - -int flv_read_packet(int flv_fd, int* type, u_int32_t* timestamp, char** data, int* size) -{ - int ret = 0; - - char th[11]; // tag header - char ts[4]; // tag size - - int32_t data_size = 0; - u_int32_t time = 0; - - char* pp; - - // read tag header - if (read(flv_fd, th, sizeof(th)) != sizeof(th)) { - ret = -1; - trace("read flv tag header failed. ret=%d", ret); - return ret; - } - - // Reserved UB [2] - // Filter UB [1] - // TagType UB [5] - *type = (int)(th[0] & 0x1F); - - // DataSize UI24 - pp = (char*)&data_size; - pp[2] = th[1]; - pp[1] = th[2]; - pp[0] = th[3]; - - // Timestamp UI24 - pp = (char*)&time; - pp[2] = th[4]; - pp[1] = th[5]; - pp[0] = th[6]; - - // TimestampExtended UI8 - pp[3] = th[7]; - - *timestamp = time; - - // check data size. - if (data_size <= 0) { - ret = -1; - trace("invalid data size. size=%d, ret=%d", data_size, ret); - return ret; - } - - // read tag data. - *size = data_size; - *data = (char*)malloc(data_size); - if (read(flv_fd, *data, data_size) != data_size) { - ret = -1; - trace("read flv tag data failed. size=%d, ret=%d", data_size, ret); - return ret; - } - - // ignore 4bytes tag size. - if (read(flv_fd, ts, sizeof(ts)) != sizeof(ts)) { - ret = -1; - trace("read flv tag size failed. ret=%d", ret); - return ret; - } - - return ret; -} diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index ddd9c9e7f..267858450 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -36,6 +36,8 @@ using namespace std; #include #include #include +#include +#include // if user want to define log, define the folowing macro. #ifndef SRS_RTMP_USER_DEFINED_LOG @@ -406,6 +408,33 @@ int64_t srs_get_time_ms() return srs_get_system_time_ms(); } +srs_amf0_t srs_amf0_parse(char* data, int size) +{ + int ret = ERROR_SUCCESS; + + srs_amf0_t amf0 = NULL; + + SrsStream stream; + if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { + return amf0; + } + + SrsAmf0Any* any = NULL; + if ((ret = SrsAmf0Any::discovery(&stream, &any)) != ERROR_SUCCESS) { + return amf0; + } + + stream.reset(); + if ((ret = any->read(&stream)) != ERROR_SUCCESS) { + srs_freep(any); + return amf0; + } + + amf0 = (srs_amf0_t)any; + + return amf0; +} + #ifdef __cplusplus } #endif diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index 4254e64b8..b91e680bc 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -157,7 +157,14 @@ int srs_version_revision(); /** * utilities */ -extern int64_t srs_get_time_ms(); +int64_t srs_get_time_ms(); + +/** +* amf0 codec +*/ +// the output handler. +typedef void* srs_amf0_t; +srs_amf0_t srs_amf0_parse(char* data, int size); #ifdef __cplusplus } diff --git a/trunk/src/srs/srs.upp b/trunk/src/srs/srs.upp index ab3b8aaa6..27bec0aea 100755 --- a/trunk/src/srs/srs.upp +++ b/trunk/src/srs/srs.upp @@ -109,6 +109,8 @@ file ..\utest\srs_utest_handshake.hpp, ..\utest\srs_utest_handshake.cpp, research readonly separator, + ..\..\research\librtmp\srs_flv_codec.h, + ..\..\research\librtmp\srs_flv_parser.c, ..\..\research\librtmp\srs_ingest_flv.c, ..\..\research\librtmp\srs_ingest_rtmp.c, ..\..\research\librtmp\srs_play.c,