正在显示
13 个修改的文件
包含
441 行增加
和
35 行删除
| @@ -446,7 +446,8 @@ CORE_OBJS="${MODULE_OBJS[@]}" | @@ -446,7 +446,8 @@ CORE_OBJS="${MODULE_OBJS[@]}" | ||
| 446 | MODULE_ID="KERNEL" | 446 | MODULE_ID="KERNEL" |
| 447 | MODULE_DEPENDS=("CORE") | 447 | MODULE_DEPENDS=("CORE") |
| 448 | ModuleLibIncs=(${SRS_OBJS}) | 448 | ModuleLibIncs=(${SRS_OBJS}) |
| 449 | -MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream" "srs_kernel_buffer" "srs_kernel_utility") | 449 | +MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream" "srs_kernel_buffer" |
| 450 | + "srs_kernel_utility" "srs_kernel_flv") | ||
| 450 | KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh | 451 | KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh |
| 451 | KERNEL_OBJS="${MODULE_OBJS[@]}" | 452 | KERNEL_OBJS="${MODULE_OBJS[@]}" |
| 452 | # | 453 | # |
| @@ -468,8 +469,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | @@ -468,8 +469,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | ||
| 468 | "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" | 469 | "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" |
| 469 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" | 470 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" |
| 470 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" | 471 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" |
| 471 | - "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" | ||
| 472 | - "srs_app_flv") | 472 | + "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client") |
| 473 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh | 473 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh |
| 474 | APP_OBJS="${MODULE_OBJS[@]}" | 474 | APP_OBJS="${MODULE_OBJS[@]}" |
| 475 | # | 475 | # |
trunk/research/librtmp/Makefile
100644 → 100755
| @@ -3,7 +3,7 @@ GCC = gcc | @@ -3,7 +3,7 @@ GCC = gcc | ||
| 3 | ifeq ($(HANDSHAKE),) | 3 | ifeq ($(HANDSHAKE),) |
| 4 | ST_ALL = help | 4 | ST_ALL = help |
| 5 | else | 5 | else |
| 6 | - ST_ALL = srs_flv_parser srs_publish srs_play srs_ingest_flv srs_ingest_rtmp | 6 | + ST_ALL = srs_flv_parser srs_flv_injecter srs_publish srs_play srs_ingest_flv srs_ingest_rtmp |
| 7 | endif | 7 | endif |
| 8 | 8 | ||
| 9 | .PHONY: default clean help ssl nossl | 9 | .PHONY: default clean help ssl nossl |
| @@ -11,12 +11,13 @@ endif | @@ -11,12 +11,13 @@ endif | ||
| 11 | default: $(ST_ALL) | 11 | default: $(ST_ALL) |
| 12 | 12 | ||
| 13 | help: | 13 | help: |
| 14 | - @echo "Usage: make <help>|<clean>|<srs_flv_parser>|<srs_publish>|<srs_play>|<srs_ingest_flv>|<srs_ingest_rtmp>" | 14 | + @echo "Usage: make <help>|<clean>|<srs_flv_parser>|<srs_flv_injecter>|<srs_publish>|<srs_play>|<srs_ingest_flv>|<srs_ingest_rtmp>" |
| 15 | @echo " help display this help" | 15 | @echo " help display this help" |
| 16 | @echo " clean cleanup build" | 16 | @echo " clean cleanup build" |
| 17 | @echo " ssl all tools link ssl" | 17 | @echo " ssl all tools link ssl" |
| 18 | @echo " nossl all tools never link ssl" | 18 | @echo " nossl all tools never link ssl" |
| 19 | @echo " srs_flv_parser parse flv file, print detail info." | 19 | @echo " srs_flv_parser parse flv file, print detail info." |
| 20 | + @echo " srs_flv_injecter inject keyframes information to metadata." | ||
| 20 | @echo " srs_publish publish program using srs-librtmp" | 21 | @echo " srs_publish publish program using srs-librtmp" |
| 21 | @echo " srs_play play program using srs-librtmp" | 22 | @echo " srs_play play program using srs-librtmp" |
| 22 | @echo " srs_ingest_flv ingest flv file and publish to RTMP server." | 23 | @echo " srs_ingest_flv ingest flv file and publish to RTMP server." |
| @@ -29,7 +30,7 @@ help: | @@ -29,7 +30,7 @@ help: | ||
| 29 | @echo "Remark: before make this sample, user must make the srs, with/without ssl" | 30 | @echo "Remark: before make this sample, user must make the srs, with/without ssl" |
| 30 | 31 | ||
| 31 | clean: | 32 | clean: |
| 32 | - @rm -f srs_flv_parser srs_publish srs_play srs_ingest_flv srs_ingest_rtmp | 33 | + @rm -f srs_flv_parser srs_flv_injecter srs_publish srs_play srs_ingest_flv srs_ingest_rtmp |
| 33 | 34 | ||
| 34 | # srs library root | 35 | # srs library root |
| 35 | SRS_OBJS = ../../objs | 36 | SRS_OBJS = ../../objs |
| @@ -66,6 +67,9 @@ nossl: | @@ -66,6 +67,9 @@ nossl: | ||
| 66 | srs_flv_parser: srs_flv_parser.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) | 67 | srs_flv_parser: srs_flv_parser.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) |
| 67 | $(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_flv_parser | 68 | $(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_flv_parser |
| 68 | 69 | ||
| 70 | +srs_flv_injecter: srs_flv_injecter.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) | ||
| 71 | + $(GCC) srs_flv_injecter.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_flv_injecter | ||
| 72 | + | ||
| 69 | srs_publish: srs_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) | 73 | srs_publish: srs_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) |
| 70 | $(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_publish | 74 | $(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o srs_publish |
| 71 | 75 |
trunk/research/librtmp/srs_flv_injecter.c
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | +/** | ||
| 24 | +gcc srs_flv_injecter.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_flv_injecter | ||
| 25 | +*/ | ||
| 26 | + | ||
| 27 | +#include <stdio.h> | ||
| 28 | +#include <stdlib.h> | ||
| 29 | +#include <unistd.h> | ||
| 30 | + | ||
| 31 | +#include <sys/types.h> | ||
| 32 | +#include <sys/stat.h> | ||
| 33 | +#include <fcntl.h> | ||
| 34 | + | ||
| 35 | +#include "../../objs/include/srs_librtmp.h" | ||
| 36 | +#include "srs_research_public.h" | ||
| 37 | +#include "srs_flv_codec.h" | ||
| 38 | + | ||
| 39 | +int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc); | ||
| 40 | +int inject_flv(srs_flv_t ic, srs_flv_t oc); | ||
| 41 | +int main(int argc, char** argv) | ||
| 42 | +{ | ||
| 43 | + int ret = 0; | ||
| 44 | + | ||
| 45 | + // user options. | ||
| 46 | + char* in_flv_file; | ||
| 47 | + char* out_flv_file; | ||
| 48 | + // flv handler | ||
| 49 | + srs_flv_t ic = NULL; | ||
| 50 | + srs_flv_t oc = NULL; | ||
| 51 | + | ||
| 52 | + // temp variables. | ||
| 53 | + char* tmp_file; | ||
| 54 | + | ||
| 55 | + if (argc <= 2) { | ||
| 56 | + printf("inject flv file keyframes to metadata\n" | ||
| 57 | + "Usage: %s in_flv_file out_flv_file\n" | ||
| 58 | + " in_flv_file input flv file to inject.\n" | ||
| 59 | + " out_flv_file the inject output file, can be in_flv_file.\n" | ||
| 60 | + "For example:\n" | ||
| 61 | + " %s ../../doc/source.200kbps.768x320.flv injected.flv\n", | ||
| 62 | + argv[0]); | ||
| 63 | + ret = 1; | ||
| 64 | + exit(ret); | ||
| 65 | + return ret; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + in_flv_file = argv[1]; | ||
| 69 | + out_flv_file = argv[2]; | ||
| 70 | + | ||
| 71 | + tmp_file = (char*)malloc(strlen(out_flv_file) + strlen(".tmp") + 1); | ||
| 72 | + | ||
| 73 | + trace("inject flv file keyframes to metadata."); | ||
| 74 | + trace("srs(simple-rtmp-server) client librtmp library."); | ||
| 75 | + trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision()); | ||
| 76 | + trace("input: %s", in_flv_file); | ||
| 77 | + trace("output: %s", out_flv_file); | ||
| 78 | + | ||
| 79 | + if ((ret = process(in_flv_file, out_flv_file, &ic, &oc)) != 0) { | ||
| 80 | + return ret; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + srs_flv_close(ic); | ||
| 84 | + srs_flv_close(oc); | ||
| 85 | + free(tmp_file); | ||
| 86 | + | ||
| 87 | + return ret; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc) | ||
| 91 | +{ | ||
| 92 | + int ret = 0; | ||
| 93 | + | ||
| 94 | + if ((*pic = srs_flv_open_read(in_flv_file)) == NULL) { | ||
| 95 | + ret = 2; | ||
| 96 | + trace("open input flv file failed. ret=%d", ret); | ||
| 97 | + return ret; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + if ((*poc = srs_flv_open_write(out_flv_file)) == NULL) { | ||
| 101 | + ret = 2; | ||
| 102 | + trace("open output flv file failed. ret=%d", ret); | ||
| 103 | + return ret; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + if ((ret = inject_flv(*pic, *poc)) != 0) { | ||
| 107 | + return ret; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + return ret; | ||
| 111 | +} | ||
| 112 | + | ||
| 113 | +int inject_flv(srs_flv_t ic, srs_flv_t oc) | ||
| 114 | +{ | ||
| 115 | + int ret = 0; | ||
| 116 | + | ||
| 117 | + return ret; | ||
| 118 | +} |
| @@ -36,7 +36,7 @@ gcc srs_ingest_flv.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest_ | @@ -36,7 +36,7 @@ gcc srs_ingest_flv.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest_ | ||
| 36 | #include "srs_research_public.h" | 36 | #include "srs_research_public.h" |
| 37 | #include "srs_flv_codec.h" | 37 | #include "srs_flv_codec.h" |
| 38 | 38 | ||
| 39 | -int parse_flv(int flv_fd); | 39 | +int parse_flv(srs_flv_t flv); |
| 40 | int main(int argc, char** argv) | 40 | int main(int argc, char** argv) |
| 41 | { | 41 | { |
| 42 | int ret = 0; | 42 | int ret = 0; |
| @@ -44,7 +44,7 @@ int main(int argc, char** argv) | @@ -44,7 +44,7 @@ int main(int argc, char** argv) | ||
| 44 | // user options. | 44 | // user options. |
| 45 | char* in_flv_file; | 45 | char* in_flv_file; |
| 46 | // flv handler | 46 | // flv handler |
| 47 | - int flv_fd; | 47 | + srs_flv_t flv; |
| 48 | 48 | ||
| 49 | if (argc <= 1) { | 49 | if (argc <= 1) { |
| 50 | printf("parse and show flv file detail\n" | 50 | printf("parse and show flv file detail\n" |
| @@ -65,15 +65,14 @@ int main(int argc, char** argv) | @@ -65,15 +65,14 @@ int main(int argc, char** argv) | ||
| 65 | trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision()); | 65 | trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision()); |
| 66 | trace("input: %s", in_flv_file); | 66 | trace("input: %s", in_flv_file); |
| 67 | 67 | ||
| 68 | - flv_fd = open_flv_file(in_flv_file); | ||
| 69 | - if (flv_fd <= 0) { | 68 | + if ((flv = srs_flv_open_read(in_flv_file)) == NULL) { |
| 70 | ret = 2; | 69 | ret = 2; |
| 71 | trace("open flv file failed. ret=%d", ret); | 70 | trace("open flv file failed. ret=%d", ret); |
| 72 | return ret; | 71 | return ret; |
| 73 | } | 72 | } |
| 74 | 73 | ||
| 75 | - ret = parse_flv(flv_fd); | ||
| 76 | - close_flv_file(flv_fd); | 74 | + ret = parse_flv(flv); |
| 75 | + srs_flv_close(flv); | ||
| 77 | 76 | ||
| 78 | return ret; | 77 | return ret; |
| 79 | } | 78 | } |
| @@ -207,26 +206,30 @@ int parse_video_data(u_int32_t timestamp, char* data, int size, int64_t offset) | @@ -207,26 +206,30 @@ int parse_video_data(u_int32_t timestamp, char* data, int size, int64_t offset) | ||
| 207 | return ret; | 206 | return ret; |
| 208 | } | 207 | } |
| 209 | 208 | ||
| 210 | -int parse_flv(int flv_fd) | 209 | +int parse_flv(srs_flv_t flv) |
| 211 | { | 210 | { |
| 212 | int ret = 0; | 211 | int ret = 0; |
| 213 | 212 | ||
| 214 | - if ((ret = flv_open_ic(flv_fd)) != 0) { | ||
| 215 | - return ret; | ||
| 216 | - } | ||
| 217 | - | 213 | + // flv header |
| 214 | + char header[13]; | ||
| 218 | // packet data | 215 | // packet data |
| 219 | - int type, size; | 216 | + char type; |
| 220 | u_int32_t timestamp = 0; | 217 | u_int32_t timestamp = 0; |
| 221 | char* data = NULL; | 218 | char* data = NULL; |
| 219 | + int32_t size; | ||
| 222 | int64_t offset = 0; | 220 | int64_t offset = 0; |
| 223 | 221 | ||
| 222 | + if ((ret = srs_flv_read_header(flv, header)) != 0) { | ||
| 223 | + return ret; | ||
| 224 | + } | ||
| 225 | + | ||
| 224 | trace("start parse flv"); | 226 | trace("start parse flv"); |
| 225 | for (;;) { | 227 | for (;;) { |
| 226 | - offset = lseek(flv_fd, 0, SEEK_CUR); | 228 | + offset = srs_flv_tellg(flv); |
| 227 | 229 | ||
| 228 | - if ((ret = flv_read_packet(flv_fd, &type, ×tamp, &data, &size)) != 0) { | ||
| 229 | - if (ret == ERROR_FLV_CODEC_EOF) { | 230 | + // tag header |
| 231 | + if ((ret = srs_flv_read_tag_header(flv, &type, &size, ×tamp)) != 0) { | ||
| 232 | + if (srs_flv_is_eof(ret)) { | ||
| 230 | trace("parse completed."); | 233 | trace("parse completed."); |
| 231 | return 0; | 234 | return 0; |
| 232 | } | 235 | } |
| @@ -234,6 +237,16 @@ int parse_flv(int flv_fd) | @@ -234,6 +237,16 @@ int parse_flv(int flv_fd) | ||
| 234 | return ret; | 237 | return ret; |
| 235 | } | 238 | } |
| 236 | 239 | ||
| 240 | + if (size <= 0) { | ||
| 241 | + trace("invalid size=%d", size); | ||
| 242 | + break; | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + data = (char*)malloc(size); | ||
| 246 | + if ((ret = srs_flv_read_tag_data(flv, data, size)) != 0) { | ||
| 247 | + return ret; | ||
| 248 | + } | ||
| 249 | + | ||
| 237 | // data tag | 250 | // data tag |
| 238 | if (type == SRS_RTMP_TYPE_AUDIO) { | 251 | if (type == SRS_RTMP_TYPE_AUDIO) { |
| 239 | if ((ret = parse_audio_data(timestamp, data, size, offset)) != 0) { | 252 | if ((ret = parse_audio_data(timestamp, data, size, offset)) != 0) { |
| @@ -39,7 +39,7 @@ using namespace std; | @@ -39,7 +39,7 @@ using namespace std; | ||
| 39 | #include <srs_kernel_utility.hpp> | 39 | #include <srs_kernel_utility.hpp> |
| 40 | #include <srs_app_http_hooks.hpp> | 40 | #include <srs_app_http_hooks.hpp> |
| 41 | #include <srs_app_codec.hpp> | 41 | #include <srs_app_codec.hpp> |
| 42 | -#include <srs_app_flv.hpp> | 42 | +#include <srs_kernel_flv.hpp> |
| 43 | 43 | ||
| 44 | SrsFlvSegment::SrsFlvSegment() | 44 | SrsFlvSegment::SrsFlvSegment() |
| 45 | { | 45 | { |
| @@ -40,7 +40,7 @@ using namespace std; | @@ -40,7 +40,7 @@ using namespace std; | ||
| 40 | #include <srs_core_autofree.hpp> | 40 | #include <srs_core_autofree.hpp> |
| 41 | #include <srs_app_json.hpp> | 41 | #include <srs_app_json.hpp> |
| 42 | #include <srs_app_config.hpp> | 42 | #include <srs_app_config.hpp> |
| 43 | -#include <srs_app_flv.hpp> | 43 | +#include <srs_kernel_flv.hpp> |
| 44 | 44 | ||
| 45 | #define SRS_HTTP_DEFAULT_PAGE "index.html" | 45 | #define SRS_HTTP_DEFAULT_PAGE "index.html" |
| 46 | 46 |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR "0" | 32 | #define VERSION_MAJOR "0" |
| 33 | #define VERSION_MINOR "9" | 33 | #define VERSION_MINOR "9" |
| 34 | -#define VERSION_REVISION "120" | 34 | +#define VERSION_REVISION "121" |
| 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION |
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
| @@ -118,6 +118,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -118,6 +118,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 118 | #define ERROR_SYSTEM_FILE_RENAME 429 | 118 | #define ERROR_SYSTEM_FILE_RENAME 429 |
| 119 | #define ERROR_SYSTEM_CREATE_PIPE 430 | 119 | #define ERROR_SYSTEM_CREATE_PIPE 430 |
| 120 | #define ERROR_SYSTEM_FILE_SEEK 431 | 120 | #define ERROR_SYSTEM_FILE_SEEK 431 |
| 121 | +#define ERROR_SYSTEM_FLV_HEADER 432 | ||
| 121 | 122 | ||
| 122 | // see librtmp. | 123 | // see librtmp. |
| 123 | // failed when open ssl create the dh | 124 | // failed when open ssl create the dh |
| @@ -21,22 +21,17 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | @@ -21,22 +21,17 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | -#include <srs_app_flv.hpp> | 24 | +#include <srs_kernel_flv.hpp> |
| 25 | 25 | ||
| 26 | #include <fcntl.h> | 26 | #include <fcntl.h> |
| 27 | #include <sstream> | 27 | #include <sstream> |
| 28 | using namespace std; | 28 | using namespace std; |
| 29 | 29 | ||
| 30 | -#include <srs_app_config.hpp> | 30 | +#include <srs_kernel_log.hpp> |
| 31 | #include <srs_kernel_error.hpp> | 31 | #include <srs_kernel_error.hpp> |
| 32 | -#include <srs_protocol_rtmp.hpp> | ||
| 33 | -#include <srs_protocol_rtmp_stack.hpp> | ||
| 34 | -#include <srs_app_source.hpp> | ||
| 35 | #include <srs_core_autofree.hpp> | 32 | #include <srs_core_autofree.hpp> |
| 36 | #include <srs_kernel_stream.hpp> | 33 | #include <srs_kernel_stream.hpp> |
| 37 | #include <srs_kernel_utility.hpp> | 34 | #include <srs_kernel_utility.hpp> |
| 38 | -#include <srs_app_http_hooks.hpp> | ||
| 39 | -#include <srs_app_codec.hpp> | ||
| 40 | 35 | ||
| 41 | #define SRS_FLV_TAG_HEADER_SIZE 11 | 36 | #define SRS_FLV_TAG_HEADER_SIZE 11 |
| 42 | #define SRS_FLV_PREVIOUS_TAG_SIZE 4 | 37 | #define SRS_FLV_PREVIOUS_TAG_SIZE 4 |
| @@ -509,3 +504,109 @@ int SrsFlvFastDecoder::lseek(int64_t offset) | @@ -509,3 +504,109 @@ int SrsFlvFastDecoder::lseek(int64_t offset) | ||
| 509 | 504 | ||
| 510 | return ret; | 505 | return ret; |
| 511 | } | 506 | } |
| 507 | + | ||
| 508 | +SrsFlvDecoder::SrsFlvDecoder() | ||
| 509 | +{ | ||
| 510 | + _fs = NULL; | ||
| 511 | + tag_stream = new SrsStream(); | ||
| 512 | +} | ||
| 513 | + | ||
| 514 | +SrsFlvDecoder::~SrsFlvDecoder() | ||
| 515 | +{ | ||
| 516 | + srs_freep(tag_stream); | ||
| 517 | +} | ||
| 518 | + | ||
| 519 | +int SrsFlvDecoder::initialize(SrsFileStream* fs) | ||
| 520 | +{ | ||
| 521 | + int ret = ERROR_SUCCESS; | ||
| 522 | + | ||
| 523 | + _fs = fs; | ||
| 524 | + | ||
| 525 | + return ret; | ||
| 526 | +} | ||
| 527 | + | ||
| 528 | +int SrsFlvDecoder::read_header(char header[9]) | ||
| 529 | +{ | ||
| 530 | + int ret = ERROR_SUCCESS; | ||
| 531 | + | ||
| 532 | + if ((ret = _fs->read(header, 9, NULL)) != ERROR_SUCCESS) { | ||
| 533 | + return ret; | ||
| 534 | + } | ||
| 535 | + | ||
| 536 | + char* h = header; | ||
| 537 | + if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { | ||
| 538 | + ret = ERROR_SYSTEM_FLV_HEADER; | ||
| 539 | + srs_warn("flv header must start with FLV. ret=%d", ret); | ||
| 540 | + return ret; | ||
| 541 | + } | ||
| 542 | + | ||
| 543 | + return ret; | ||
| 544 | +} | ||
| 545 | + | ||
| 546 | +int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime) | ||
| 547 | +{ | ||
| 548 | + int ret = ERROR_SUCCESS; | ||
| 549 | + | ||
| 550 | + char th[11]; // tag header | ||
| 551 | + | ||
| 552 | + // read tag header | ||
| 553 | + if ((ret = _fs->read(th, 11, NULL)) != ERROR_SUCCESS) { | ||
| 554 | + if (ret != ERROR_SYSTEM_FILE_EOF) { | ||
| 555 | + srs_error("read flv tag header failed. ret=%d", ret); | ||
| 556 | + } | ||
| 557 | + return ret; | ||
| 558 | + } | ||
| 559 | + | ||
| 560 | + // Reserved UB [2] | ||
| 561 | + // Filter UB [1] | ||
| 562 | + // TagType UB [5] | ||
| 563 | + *ptype = (int)(th[0] & 0x1F); | ||
| 564 | + | ||
| 565 | + // DataSize UI24 | ||
| 566 | + char* pp = (char*)pdata_size; | ||
| 567 | + pp[2] = th[1]; | ||
| 568 | + pp[1] = th[2]; | ||
| 569 | + pp[0] = th[3]; | ||
| 570 | + | ||
| 571 | + // Timestamp UI24 | ||
| 572 | + pp = (char*)ptime; | ||
| 573 | + pp[2] = th[4]; | ||
| 574 | + pp[1] = th[5]; | ||
| 575 | + pp[0] = th[6]; | ||
| 576 | + | ||
| 577 | + // TimestampExtended UI8 | ||
| 578 | + pp[3] = th[7]; | ||
| 579 | + | ||
| 580 | + return ret; | ||
| 581 | +} | ||
| 582 | + | ||
| 583 | +int SrsFlvDecoder::read_tag_data(char* data, int32_t size) | ||
| 584 | +{ | ||
| 585 | + int ret = ERROR_SUCCESS; | ||
| 586 | + | ||
| 587 | + if ((ret = _fs->read(data, size, NULL)) != ERROR_SUCCESS) { | ||
| 588 | + if (ret != ERROR_SYSTEM_FILE_EOF) { | ||
| 589 | + srs_error("read flv tag header failed. ret=%d", ret); | ||
| 590 | + } | ||
| 591 | + return ret; | ||
| 592 | + } | ||
| 593 | + | ||
| 594 | + return ret; | ||
| 595 | + | ||
| 596 | +} | ||
| 597 | + | ||
| 598 | +int SrsFlvDecoder::read_previous_tag_size(char ts[4]) | ||
| 599 | +{ | ||
| 600 | + int ret = ERROR_SUCCESS; | ||
| 601 | + | ||
| 602 | + // ignore 4bytes tag size. | ||
| 603 | + if ((ret = _fs->read(ts, 4, NULL)) != ERROR_SUCCESS) { | ||
| 604 | + if (ret != ERROR_SYSTEM_FILE_EOF) { | ||
| 605 | + srs_error("read flv previous tag size failed. ret=%d", ret); | ||
| 606 | + } | ||
| 607 | + return ret; | ||
| 608 | + } | ||
| 609 | + | ||
| 610 | + return ret; | ||
| 611 | +} | ||
| 612 | + |
| @@ -25,7 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -25,7 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 25 | #define SRS_APP_FLV_HPP | 25 | #define SRS_APP_FLV_HPP |
| 26 | 26 | ||
| 27 | /* | 27 | /* |
| 28 | -#include <srs_app_flv.hpp> | 28 | +#include <srs_kernel_flv.hpp> |
| 29 | */ | 29 | */ |
| 30 | #include <srs_core.hpp> | 30 | #include <srs_core.hpp> |
| 31 | 31 | ||
| @@ -142,4 +142,29 @@ public: | @@ -142,4 +142,29 @@ public: | ||
| 142 | virtual int lseek(int64_t offset); | 142 | virtual int lseek(int64_t offset); |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | +/** | ||
| 146 | +* decode flv file. | ||
| 147 | +*/ | ||
| 148 | +class SrsFlvDecoder | ||
| 149 | +{ | ||
| 150 | +private: | ||
| 151 | + SrsFileStream* _fs; | ||
| 152 | +private: | ||
| 153 | + SrsStream* tag_stream; | ||
| 154 | +public: | ||
| 155 | + SrsFlvDecoder(); | ||
| 156 | + virtual ~SrsFlvDecoder(); | ||
| 157 | +public: | ||
| 158 | + /** | ||
| 159 | + * initialize the underlayer file stream, | ||
| 160 | + * user can initialize multiple times to decode multiple flv files. | ||
| 161 | + */ | ||
| 162 | + virtual int initialize(SrsFileStream* fs); | ||
| 163 | +public: | ||
| 164 | + virtual int read_header(char header[9]); | ||
| 165 | + virtual int read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime); | ||
| 166 | + virtual int read_tag_data(char* data, int32_t size); | ||
| 167 | + virtual int read_previous_tag_size(char ts[4]); | ||
| 168 | +}; | ||
| 169 | + | ||
| 145 | #endif | 170 | #endif |
| @@ -39,6 +39,7 @@ using namespace std; | @@ -39,6 +39,7 @@ using namespace std; | ||
| 39 | #include <srs_kernel_utility.hpp> | 39 | #include <srs_kernel_utility.hpp> |
| 40 | #include <srs_kernel_stream.hpp> | 40 | #include <srs_kernel_stream.hpp> |
| 41 | #include <srs_protocol_amf0.hpp> | 41 | #include <srs_protocol_amf0.hpp> |
| 42 | +#include <srs_kernel_flv.hpp> | ||
| 42 | 43 | ||
| 43 | // if user want to define log, define the folowing macro. | 44 | // if user want to define log, define the folowing macro. |
| 44 | #ifndef SRS_RTMP_USER_DEFINED_LOG | 45 | #ifndef SRS_RTMP_USER_DEFINED_LOG |
| @@ -382,6 +383,124 @@ int64_t srs_get_time_ms() | @@ -382,6 +383,124 @@ int64_t srs_get_time_ms() | ||
| 382 | return srs_get_system_time_ms(); | 383 | return srs_get_system_time_ms(); |
| 383 | } | 384 | } |
| 384 | 385 | ||
| 386 | +struct FlvContext | ||
| 387 | +{ | ||
| 388 | + SrsFileStream fs; | ||
| 389 | + SrsFlvEncoder enc; | ||
| 390 | + SrsFlvDecoder dec; | ||
| 391 | +}; | ||
| 392 | + | ||
| 393 | +srs_flv_t srs_flv_open_read(const char* file) | ||
| 394 | +{ | ||
| 395 | + int ret = ERROR_SUCCESS; | ||
| 396 | + | ||
| 397 | + FlvContext* flv = new FlvContext(); | ||
| 398 | + | ||
| 399 | + if ((ret = flv->fs.open_read(file)) != ERROR_SUCCESS) { | ||
| 400 | + srs_freep(flv); | ||
| 401 | + return NULL; | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + if ((ret = flv->enc.initialize(&flv->fs)) != ERROR_SUCCESS) { | ||
| 405 | + srs_freep(flv); | ||
| 406 | + return NULL; | ||
| 407 | + } | ||
| 408 | + | ||
| 409 | + if ((ret = flv->dec.initialize(&flv->fs)) != ERROR_SUCCESS) { | ||
| 410 | + srs_freep(flv); | ||
| 411 | + return NULL; | ||
| 412 | + } | ||
| 413 | + | ||
| 414 | + return flv; | ||
| 415 | +} | ||
| 416 | + | ||
| 417 | +srs_flv_t srs_flv_open_write(const char* file) | ||
| 418 | +{ | ||
| 419 | + int ret = ERROR_SUCCESS; | ||
| 420 | + | ||
| 421 | + FlvContext* flv = new FlvContext(); | ||
| 422 | + | ||
| 423 | + if ((ret = flv->fs.open_write(file)) != ERROR_SUCCESS) { | ||
| 424 | + srs_freep(flv); | ||
| 425 | + return NULL; | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + if ((ret = flv->enc.initialize(&flv->fs)) != ERROR_SUCCESS) { | ||
| 429 | + srs_freep(flv); | ||
| 430 | + return NULL; | ||
| 431 | + } | ||
| 432 | + | ||
| 433 | + if ((ret = flv->dec.initialize(&flv->fs)) != ERROR_SUCCESS) { | ||
| 434 | + srs_freep(flv); | ||
| 435 | + return NULL; | ||
| 436 | + } | ||
| 437 | + | ||
| 438 | + return flv; | ||
| 439 | +} | ||
| 440 | + | ||
| 441 | +void srs_flv_close(srs_flv_t flv) | ||
| 442 | +{ | ||
| 443 | + FlvContext* context = (FlvContext*)flv; | ||
| 444 | + srs_freep(context); | ||
| 445 | +} | ||
| 446 | + | ||
| 447 | +int srs_flv_read_header(srs_flv_t flv, char header[9]) | ||
| 448 | +{ | ||
| 449 | + int ret = ERROR_SUCCESS; | ||
| 450 | + | ||
| 451 | + FlvContext* context = (FlvContext*)flv; | ||
| 452 | + if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) { | ||
| 453 | + return ret; | ||
| 454 | + } | ||
| 455 | + | ||
| 456 | + char ts[4]; // tag size | ||
| 457 | + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { | ||
| 458 | + return ret; | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | + return ret; | ||
| 462 | +} | ||
| 463 | + | ||
| 464 | +int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime) | ||
| 465 | +{ | ||
| 466 | + int ret = ERROR_SUCCESS; | ||
| 467 | + | ||
| 468 | + FlvContext* context = (FlvContext*)flv; | ||
| 469 | + if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) { | ||
| 470 | + return ret; | ||
| 471 | + } | ||
| 472 | + | ||
| 473 | + return ret; | ||
| 474 | +} | ||
| 475 | + | ||
| 476 | +int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size) | ||
| 477 | +{ | ||
| 478 | + int ret = ERROR_SUCCESS; | ||
| 479 | + | ||
| 480 | + FlvContext* context = (FlvContext*)flv; | ||
| 481 | + if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) { | ||
| 482 | + return ret; | ||
| 483 | + } | ||
| 484 | + | ||
| 485 | + char ts[4]; // tag size | ||
| 486 | + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { | ||
| 487 | + return ret; | ||
| 488 | + } | ||
| 489 | + | ||
| 490 | + return ret; | ||
| 491 | +} | ||
| 492 | + | ||
| 493 | +int64_t srs_flv_tellg(srs_flv_t flv) | ||
| 494 | +{ | ||
| 495 | + FlvContext* context = (FlvContext*)flv; | ||
| 496 | + return context->fs.tellg(); | ||
| 497 | +} | ||
| 498 | + | ||
| 499 | +flv_bool srs_flv_is_eof(int error_code) | ||
| 500 | +{ | ||
| 501 | + return error_code == ERROR_SYSTEM_FILE_EOF; | ||
| 502 | +} | ||
| 503 | + | ||
| 385 | srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) | 504 | srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) |
| 386 | { | 505 | { |
| 387 | int ret = ERROR_SUCCESS; | 506 | int ret = ERROR_SUCCESS; |
| @@ -152,6 +152,25 @@ int srs_version_revision(); | @@ -152,6 +152,25 @@ int srs_version_revision(); | ||
| 152 | int64_t srs_get_time_ms(); | 152 | int64_t srs_get_time_ms(); |
| 153 | 153 | ||
| 154 | /** | 154 | /** |
| 155 | +* flv codec | ||
| 156 | +*/ | ||
| 157 | +typedef void* srs_flv_t; | ||
| 158 | +typedef int flv_bool; | ||
| 159 | +srs_flv_t srs_flv_open_read(const char* file); | ||
| 160 | +srs_flv_t srs_flv_open_write(const char* file); | ||
| 161 | +void srs_flv_close(srs_flv_t flv); | ||
| 162 | +/* read the flv header. 9bytes header. drop the 4bytes zero previous tag size */ | ||
| 163 | +int srs_flv_read_header(srs_flv_t flv, char header[9]); | ||
| 164 | +/* read the flv tag header, 1bytes tag, 3bytes data_size, 4bytes time, 3bytes stream id. */ | ||
| 165 | +int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime); | ||
| 166 | +/* read the tag data. drop the 4bytes previous tag size */ | ||
| 167 | +int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size); | ||
| 168 | +/* file stream tellg to get offset */ | ||
| 169 | +int64_t srs_flv_tellg(srs_flv_t flv); | ||
| 170 | +/* whether the error code indicates EOF */ | ||
| 171 | +flv_bool srs_flv_is_eof(int error_code); | ||
| 172 | + | ||
| 173 | +/** | ||
| 155 | * amf0 codec | 174 | * amf0 codec |
| 156 | */ | 175 | */ |
| 157 | /* the output handler. */ | 176 | /* the output handler. */ |
| @@ -184,7 +203,12 @@ srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index); | @@ -184,7 +203,12 @@ srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index); | ||
| 184 | /* strict array value converter */ | 203 | /* strict array value converter */ |
| 185 | int srs_amf0_strict_array_property_count(srs_amf0_t amf0); | 204 | int srs_amf0_strict_array_property_count(srs_amf0_t amf0); |
| 186 | srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index); | 205 | srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index); |
| 187 | -/* human readable print */ | 206 | +/** |
| 207 | +* human readable print | ||
| 208 | +* @param pdata, output the heap data, | ||
| 209 | +* user must use srs_amf0_free_bytes to free it. | ||
| 210 | +* @return return the *pdata for print. | ||
| 211 | +*/ | ||
| 188 | char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); | 212 | char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); |
| 189 | 213 | ||
| 190 | #ifdef __cplusplus | 214 | #ifdef __cplusplus |
| @@ -19,6 +19,8 @@ file | @@ -19,6 +19,8 @@ file | ||
| 19 | ..\kernel\srs_kernel_buffer.cpp, | 19 | ..\kernel\srs_kernel_buffer.cpp, |
| 20 | ..\kernel\srs_kernel_error.hpp, | 20 | ..\kernel\srs_kernel_error.hpp, |
| 21 | ..\kernel\srs_kernel_error.cpp, | 21 | ..\kernel\srs_kernel_error.cpp, |
| 22 | + ..\kernel\srs_kernel_flv.hpp, | ||
| 23 | + ..\kernel\srs_kernel_flv.cpp, | ||
| 22 | ..\kernel\srs_kernel_log.hpp, | 24 | ..\kernel\srs_kernel_log.hpp, |
| 23 | ..\kernel\srs_kernel_log.cpp, | 25 | ..\kernel\srs_kernel_log.cpp, |
| 24 | ..\kernel\srs_kernel_stream.hpp, | 26 | ..\kernel\srs_kernel_stream.hpp, |
| @@ -57,8 +59,6 @@ file | @@ -57,8 +59,6 @@ file | ||
| 57 | ..\app\srs_app_encoder.cpp, | 59 | ..\app\srs_app_encoder.cpp, |
| 58 | ..\app\srs_app_ffmpeg.hpp, | 60 | ..\app\srs_app_ffmpeg.hpp, |
| 59 | ..\app\srs_app_ffmpeg.cpp, | 61 | ..\app\srs_app_ffmpeg.cpp, |
| 60 | - ..\app\srs_app_flv.hpp, | ||
| 61 | - ..\app\srs_app_flv.cpp, | ||
| 62 | ..\app\srs_app_forward.hpp, | 62 | ..\app\srs_app_forward.hpp, |
| 63 | ..\app\srs_app_forward.cpp, | 63 | ..\app\srs_app_forward.cpp, |
| 64 | ..\app\srs_app_heartbeat.hpp, | 64 | ..\app\srs_app_heartbeat.hpp, |
| @@ -112,6 +112,7 @@ file | @@ -112,6 +112,7 @@ file | ||
| 112 | ..\utest\srs_utest_handshake.cpp, | 112 | ..\utest\srs_utest_handshake.cpp, |
| 113 | research readonly separator, | 113 | research readonly separator, |
| 114 | ..\..\research\librtmp\srs_flv_codec.h, | 114 | ..\..\research\librtmp\srs_flv_codec.h, |
| 115 | + ..\..\research\librtmp\srs_flv_injecter.c, | ||
| 115 | ..\..\research\librtmp\srs_flv_parser.c, | 116 | ..\..\research\librtmp\srs_flv_parser.c, |
| 116 | ..\..\research\librtmp\srs_ingest_flv.c, | 117 | ..\..\research\librtmp\srs_ingest_flv.c, |
| 117 | ..\..\research\librtmp\srs_ingest_rtmp.c, | 118 | ..\..\research\librtmp\srs_ingest_rtmp.c, |
-
请 注册 或 登录 后发表评论