From 608083d42fcd8f71279e2a810245909d10bc9712 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 28 May 2014 15:37:06 +0800 Subject: [PATCH] add flv injecter, add flv codec to librtmp. --- trunk/configure | 6 +- trunk/research/librtmp/Makefile | 10 +- trunk/research/librtmp/srs_flv_injecter.c | 118 +++++++++++++++++ trunk/research/librtmp/srs_flv_parser.c | 47 ++++--- trunk/src/app/srs_app_dvr.cpp | 2 +- trunk/src/app/srs_app_http_conn.cpp | 2 +- trunk/src/core/srs_core.hpp | 2 +- trunk/src/kernel/srs_kernel_error.hpp | 1 + .../srs_kernel_flv.cpp} | 115 +++++++++++++++-- .../srs_kernel_flv.hpp} | 27 +++- trunk/src/libs/srs_librtmp.cpp | 119 ++++++++++++++++++ trunk/src/libs/srs_librtmp.hpp | 26 +++- trunk/src/srs/srs.upp | 5 +- 13 files changed, 443 insertions(+), 37 deletions(-) mode change 100644 => 100755 trunk/research/librtmp/Makefile create mode 100644 trunk/research/librtmp/srs_flv_injecter.c rename trunk/src/{app/srs_app_flv.cpp => kernel/srs_kernel_flv.cpp} (86%) rename trunk/src/{app/srs_app_flv.hpp => kernel/srs_kernel_flv.hpp} (85%) diff --git a/trunk/configure b/trunk/configure index c00a29285..836c7660b 100755 --- a/trunk/configure +++ b/trunk/configure @@ -446,7 +446,8 @@ CORE_OBJS="${MODULE_OBJS[@]}" MODULE_ID="KERNEL" MODULE_DEPENDS=("CORE") ModuleLibIncs=(${SRS_OBJS}) -MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream" "srs_kernel_buffer" "srs_kernel_utility") +MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream" "srs_kernel_buffer" + "srs_kernel_utility" "srs_kernel_flv") KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh KERNEL_OBJS="${MODULE_OBJS[@]}" # @@ -468,8 +469,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" - "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" - "srs_app_flv") + "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client") APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh APP_OBJS="${MODULE_OBJS[@]}" # diff --git a/trunk/research/librtmp/Makefile b/trunk/research/librtmp/Makefile old mode 100644 new mode 100755 index 9caab7f05..76b420dfd --- a/trunk/research/librtmp/Makefile +++ b/trunk/research/librtmp/Makefile @@ -3,7 +3,7 @@ GCC = gcc ifeq ($(HANDSHAKE),) ST_ALL = help else - ST_ALL = srs_flv_parser srs_publish srs_play srs_ingest_flv srs_ingest_rtmp + ST_ALL = srs_flv_parser srs_flv_injecter srs_publish srs_play srs_ingest_flv srs_ingest_rtmp endif .PHONY: default clean help ssl nossl @@ -11,12 +11,13 @@ endif default: $(ST_ALL) help: - @echo "Usage: make ||||||" + @echo "Usage: make |||||||" @echo " help display this help" @echo " clean cleanup build" @echo " ssl all tools link ssl" @echo " nossl all tools never link ssl" @echo " srs_flv_parser parse flv file, print detail info." + @echo " srs_flv_injecter inject keyframes information to metadata." @echo " srs_publish publish program using srs-librtmp" @echo " srs_play play program using srs-librtmp" @echo " srs_ingest_flv ingest flv file and publish to RTMP server." @@ -29,7 +30,7 @@ help: @echo "Remark: before make this sample, user must make the srs, with/without ssl" clean: - @rm -f srs_flv_parser srs_publish srs_play srs_ingest_flv srs_ingest_rtmp + @rm -f srs_flv_parser srs_flv_injecter srs_publish srs_play srs_ingest_flv srs_ingest_rtmp # srs library root SRS_OBJS = ../../objs @@ -66,6 +67,9 @@ nossl: srs_flv_parser: 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 +srs_flv_injecter: srs_flv_injecter.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) + $(GCC) srs_flv_injecter.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_flv_injecter + srs_publish: 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 diff --git a/trunk/research/librtmp/srs_flv_injecter.c b/trunk/research/librtmp/srs_flv_injecter.c new file mode 100644 index 000000000..3828b62fe --- /dev/null +++ b/trunk/research/librtmp/srs_flv_injecter.c @@ -0,0 +1,118 @@ +/* +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. +*/ +/** +gcc srs_flv_injecter.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_flv_injecter +*/ + +#include +#include +#include + +#include +#include +#include + +#include "../../objs/include/srs_librtmp.h" +#include "srs_research_public.h" +#include "srs_flv_codec.h" + +int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc); +int inject_flv(srs_flv_t ic, srs_flv_t oc); +int main(int argc, char** argv) +{ + int ret = 0; + + // user options. + char* in_flv_file; + char* out_flv_file; + // flv handler + srs_flv_t ic = NULL; + srs_flv_t oc = NULL; + + // temp variables. + char* tmp_file; + + if (argc <= 2) { + printf("inject flv file keyframes to metadata\n" + "Usage: %s in_flv_file out_flv_file\n" + " in_flv_file input flv file to inject.\n" + " out_flv_file the inject output file, can be in_flv_file.\n" + "For example:\n" + " %s ../../doc/source.200kbps.768x320.flv injected.flv\n", + argv[0]); + ret = 1; + exit(ret); + return ret; + } + + in_flv_file = argv[1]; + out_flv_file = argv[2]; + + tmp_file = (char*)malloc(strlen(out_flv_file) + strlen(".tmp") + 1); + + trace("inject flv file keyframes to metadata."); + trace("srs(simple-rtmp-server) client librtmp library."); + trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision()); + trace("input: %s", in_flv_file); + trace("output: %s", out_flv_file); + + if ((ret = process(in_flv_file, out_flv_file, &ic, &oc)) != 0) { + return ret; + } + + srs_flv_close(ic); + srs_flv_close(oc); + free(tmp_file); + + return ret; +} + +int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc) +{ + int ret = 0; + + if ((*pic = srs_flv_open_read(in_flv_file)) == NULL) { + ret = 2; + trace("open input flv file failed. ret=%d", ret); + return ret; + } + + if ((*poc = srs_flv_open_write(out_flv_file)) == NULL) { + ret = 2; + trace("open output flv file failed. ret=%d", ret); + return ret; + } + + if ((ret = inject_flv(*pic, *poc)) != 0) { + return ret; + } + + return ret; +} + +int inject_flv(srs_flv_t ic, srs_flv_t oc) +{ + int ret = 0; + + return ret; +} diff --git a/trunk/research/librtmp/srs_flv_parser.c b/trunk/research/librtmp/srs_flv_parser.c index 7f0aa080b..ec0fbdad0 100644 --- a/trunk/research/librtmp/srs_flv_parser.c +++ b/trunk/research/librtmp/srs_flv_parser.c @@ -36,7 +36,7 @@ gcc srs_ingest_flv.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest_ #include "srs_research_public.h" #include "srs_flv_codec.h" -int parse_flv(int flv_fd); +int parse_flv(srs_flv_t flv); int main(int argc, char** argv) { int ret = 0; @@ -44,7 +44,7 @@ int main(int argc, char** argv) // user options. char* in_flv_file; // flv handler - int flv_fd; + srs_flv_t flv; if (argc <= 1) { printf("parse and show flv file detail\n" @@ -65,15 +65,14 @@ int main(int argc, char** argv) trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision()); trace("input: %s", in_flv_file); - flv_fd = open_flv_file(in_flv_file); - if (flv_fd <= 0) { + if ((flv = srs_flv_open_read(in_flv_file)) == NULL) { ret = 2; trace("open flv file failed. ret=%d", ret); return ret; } - ret = parse_flv(flv_fd); - close_flv_file(flv_fd); + ret = parse_flv(flv); + srs_flv_close(flv); return ret; } @@ -207,26 +206,30 @@ int parse_video_data(u_int32_t timestamp, char* data, int size, int64_t offset) return ret; } -int parse_flv(int flv_fd) +int parse_flv(srs_flv_t flv) { int ret = 0; - if ((ret = flv_open_ic(flv_fd)) != 0) { + // flv header + char header[13]; + // packet data + char type; + u_int32_t timestamp = 0; + char* data = NULL; + int32_t size; + int64_t offset = 0; + + if ((ret = srs_flv_read_header(flv, header)) != 0) { return ret; } - // packet data - int type, size; - u_int32_t timestamp = 0; - char* data = NULL; - int64_t offset = 0; - trace("start parse flv"); for (;;) { - offset = lseek(flv_fd, 0, SEEK_CUR); + offset = srs_flv_tellg(flv); - if ((ret = flv_read_packet(flv_fd, &type, ×tamp, &data, &size)) != 0) { - if (ret == ERROR_FLV_CODEC_EOF) { + // tag header + if ((ret = srs_flv_read_tag_header(flv, &type, &size, ×tamp)) != 0) { + if (srs_flv_is_eof(ret)) { trace("parse completed."); return 0; } @@ -234,6 +237,16 @@ int parse_flv(int flv_fd) return ret; } + if (size <= 0) { + trace("invalid size=%d", size); + break; + } + + data = (char*)malloc(size); + if ((ret = srs_flv_read_tag_data(flv, data, size)) != 0) { + return ret; + } + // data tag if (type == SRS_RTMP_TYPE_AUDIO) { if ((ret = parse_audio_data(timestamp, data, size, offset)) != 0) { diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp index 1d0dde5e9..e0a397165 100644 --- a/trunk/src/app/srs_app_dvr.cpp +++ b/trunk/src/app/srs_app_dvr.cpp @@ -39,7 +39,7 @@ using namespace std; #include #include #include -#include +#include SrsFlvSegment::SrsFlvSegment() { diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index d32bd7318..55f2bbb04 100644 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -40,7 +40,7 @@ using namespace std; #include #include #include -#include +#include #define SRS_HTTP_DEFAULT_PAGE "index.html" diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 94d343860..ed3275a94 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "120" +#define VERSION_REVISION "121" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "SRS" diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 3d53e737d..7636038c5 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -118,6 +118,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_SYSTEM_FILE_RENAME 429 #define ERROR_SYSTEM_CREATE_PIPE 430 #define ERROR_SYSTEM_FILE_SEEK 431 +#define ERROR_SYSTEM_FLV_HEADER 432 // see librtmp. // failed when open ssl create the dh diff --git a/trunk/src/app/srs_app_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp similarity index 86% rename from trunk/src/app/srs_app_flv.cpp rename to trunk/src/kernel/srs_kernel_flv.cpp index 42a723f5d..55501f2a2 100644 --- a/trunk/src/app/srs_app_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -21,22 +21,17 @@ 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. */ -#include +#include #include #include using namespace std; -#include +#include #include -#include -#include -#include #include #include #include -#include -#include #define SRS_FLV_TAG_HEADER_SIZE 11 #define SRS_FLV_PREVIOUS_TAG_SIZE 4 @@ -509,3 +504,109 @@ int SrsFlvFastDecoder::lseek(int64_t offset) return ret; } + +SrsFlvDecoder::SrsFlvDecoder() +{ + _fs = NULL; + tag_stream = new SrsStream(); +} + +SrsFlvDecoder::~SrsFlvDecoder() +{ + srs_freep(tag_stream); +} + +int SrsFlvDecoder::initialize(SrsFileStream* fs) +{ + int ret = ERROR_SUCCESS; + + _fs = fs; + + return ret; +} + +int SrsFlvDecoder::read_header(char header[9]) +{ + int ret = ERROR_SUCCESS; + + if ((ret = _fs->read(header, 9, NULL)) != ERROR_SUCCESS) { + return ret; + } + + char* h = header; + if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { + ret = ERROR_SYSTEM_FLV_HEADER; + srs_warn("flv header must start with FLV. ret=%d", ret); + return ret; + } + + return ret; +} + +int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime) +{ + int ret = ERROR_SUCCESS; + + char th[11]; // tag header + + // read tag header + if ((ret = _fs->read(th, 11, NULL)) != ERROR_SUCCESS) { + if (ret != ERROR_SYSTEM_FILE_EOF) { + srs_error("read flv tag header failed. ret=%d", ret); + } + return ret; + } + + // Reserved UB [2] + // Filter UB [1] + // TagType UB [5] + *ptype = (int)(th[0] & 0x1F); + + // DataSize UI24 + char* pp = (char*)pdata_size; + pp[2] = th[1]; + pp[1] = th[2]; + pp[0] = th[3]; + + // Timestamp UI24 + pp = (char*)ptime; + pp[2] = th[4]; + pp[1] = th[5]; + pp[0] = th[6]; + + // TimestampExtended UI8 + pp[3] = th[7]; + + return ret; +} + +int SrsFlvDecoder::read_tag_data(char* data, int32_t size) +{ + int ret = ERROR_SUCCESS; + + if ((ret = _fs->read(data, size, NULL)) != ERROR_SUCCESS) { + if (ret != ERROR_SYSTEM_FILE_EOF) { + srs_error("read flv tag header failed. ret=%d", ret); + } + return ret; + } + + return ret; + +} + +int SrsFlvDecoder::read_previous_tag_size(char ts[4]) +{ + int ret = ERROR_SUCCESS; + + // ignore 4bytes tag size. + if ((ret = _fs->read(ts, 4, NULL)) != ERROR_SUCCESS) { + if (ret != ERROR_SYSTEM_FILE_EOF) { + srs_error("read flv previous tag size failed. ret=%d", ret); + } + return ret; + } + + return ret; +} + diff --git a/trunk/src/app/srs_app_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp similarity index 85% rename from trunk/src/app/srs_app_flv.hpp rename to trunk/src/kernel/srs_kernel_flv.hpp index 6c8b0d76f..1d136e0d5 100644 --- a/trunk/src/app/srs_app_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -25,7 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_APP_FLV_HPP /* -#include +#include */ #include @@ -142,4 +142,29 @@ public: virtual int lseek(int64_t offset); }; +/** +* decode flv file. +*/ +class SrsFlvDecoder +{ +private: + SrsFileStream* _fs; +private: + SrsStream* tag_stream; +public: + SrsFlvDecoder(); + virtual ~SrsFlvDecoder(); +public: + /** + * initialize the underlayer file stream, + * user can initialize multiple times to decode multiple flv files. + */ + virtual int initialize(SrsFileStream* fs); +public: + virtual int read_header(char header[9]); + virtual int read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime); + virtual int read_tag_data(char* data, int32_t size); + virtual int read_previous_tag_size(char ts[4]); +}; + #endif \ No newline at end of file diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index adcefa580..10cab1a1e 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -39,6 +39,7 @@ using namespace std; #include #include #include +#include // if user want to define log, define the folowing macro. #ifndef SRS_RTMP_USER_DEFINED_LOG @@ -382,6 +383,124 @@ int64_t srs_get_time_ms() return srs_get_system_time_ms(); } +struct FlvContext +{ + SrsFileStream fs; + SrsFlvEncoder enc; + SrsFlvDecoder dec; +}; + +srs_flv_t srs_flv_open_read(const char* file) +{ + int ret = ERROR_SUCCESS; + + FlvContext* flv = new FlvContext(); + + if ((ret = flv->fs.open_read(file)) != ERROR_SUCCESS) { + srs_freep(flv); + return NULL; + } + + if ((ret = flv->enc.initialize(&flv->fs)) != ERROR_SUCCESS) { + srs_freep(flv); + return NULL; + } + + if ((ret = flv->dec.initialize(&flv->fs)) != ERROR_SUCCESS) { + srs_freep(flv); + return NULL; + } + + return flv; +} + +srs_flv_t srs_flv_open_write(const char* file) +{ + int ret = ERROR_SUCCESS; + + FlvContext* flv = new FlvContext(); + + if ((ret = flv->fs.open_write(file)) != ERROR_SUCCESS) { + srs_freep(flv); + return NULL; + } + + if ((ret = flv->enc.initialize(&flv->fs)) != ERROR_SUCCESS) { + srs_freep(flv); + return NULL; + } + + if ((ret = flv->dec.initialize(&flv->fs)) != ERROR_SUCCESS) { + srs_freep(flv); + return NULL; + } + + return flv; +} + +void srs_flv_close(srs_flv_t flv) +{ + FlvContext* context = (FlvContext*)flv; + srs_freep(context); +} + +int srs_flv_read_header(srs_flv_t flv, char header[9]) +{ + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) { + return ret; + } + + char ts[4]; // tag size + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { + return ret; + } + + return ret; +} + +int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime) +{ + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) { + return ret; + } + + return ret; +} + +int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size) +{ + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) { + return ret; + } + + char ts[4]; // tag size + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { + return ret; + } + + return ret; +} + +int64_t srs_flv_tellg(srs_flv_t flv) +{ + FlvContext* context = (FlvContext*)flv; + return context->fs.tellg(); +} + +flv_bool srs_flv_is_eof(int error_code) +{ + return error_code == ERROR_SYSTEM_FILE_EOF; +} + srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) { int ret = ERROR_SUCCESS; diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index 41f5a4d25..3b8e4e532 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -151,6 +151,25 @@ int srs_version_revision(); */ int64_t srs_get_time_ms(); +/** +* flv codec +*/ +typedef void* srs_flv_t; +typedef int flv_bool; +srs_flv_t srs_flv_open_read(const char* file); +srs_flv_t srs_flv_open_write(const char* file); +void srs_flv_close(srs_flv_t flv); +/* read the flv header. 9bytes header. drop the 4bytes zero previous tag size */ +int srs_flv_read_header(srs_flv_t flv, char header[9]); +/* read the flv tag header, 1bytes tag, 3bytes data_size, 4bytes time, 3bytes stream id. */ +int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime); +/* read the tag data. drop the 4bytes previous tag size */ +int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size); +/* file stream tellg to get offset */ +int64_t srs_flv_tellg(srs_flv_t flv); +/* whether the error code indicates EOF */ +flv_bool srs_flv_is_eof(int error_code); + /** * amf0 codec */ @@ -184,7 +203,12 @@ srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index); /* strict array value converter */ int srs_amf0_strict_array_property_count(srs_amf0_t amf0); srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index); -/* human readable print */ +/** +* human readable print +* @param pdata, output the heap data, +* user must use srs_amf0_free_bytes to free it. +* @return return the *pdata for print. +*/ char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); #ifdef __cplusplus diff --git a/trunk/src/srs/srs.upp b/trunk/src/srs/srs.upp index 82f2ed379..cb9b88010 100755 --- a/trunk/src/srs/srs.upp +++ b/trunk/src/srs/srs.upp @@ -19,6 +19,8 @@ file ..\kernel\srs_kernel_buffer.cpp, ..\kernel\srs_kernel_error.hpp, ..\kernel\srs_kernel_error.cpp, + ..\kernel\srs_kernel_flv.hpp, + ..\kernel\srs_kernel_flv.cpp, ..\kernel\srs_kernel_log.hpp, ..\kernel\srs_kernel_log.cpp, ..\kernel\srs_kernel_stream.hpp, @@ -57,8 +59,6 @@ file ..\app\srs_app_encoder.cpp, ..\app\srs_app_ffmpeg.hpp, ..\app\srs_app_ffmpeg.cpp, - ..\app\srs_app_flv.hpp, - ..\app\srs_app_flv.cpp, ..\app\srs_app_forward.hpp, ..\app\srs_app_forward.cpp, ..\app\srs_app_heartbeat.hpp, @@ -112,6 +112,7 @@ file ..\utest\srs_utest_handshake.cpp, research readonly separator, ..\..\research\librtmp\srs_flv_codec.h, + ..\..\research\librtmp\srs_flv_injecter.c, ..\..\research\librtmp\srs_flv_parser.c, ..\..\research\librtmp\srs_ingest_flv.c, ..\..\research\librtmp\srs_ingest_rtmp.c,