正在显示
11 个修改的文件
包含
690 行增加
和
171 行删除
@@ -312,14 +312,12 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | @@ -312,14 +312,12 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | ||
312 | } | 312 | } |
313 | 313 | ||
314 | // save header, send later. | 314 | // save header, send later. |
315 | - char* flv_header = NULL; | ||
316 | - int flv_size = 0; | 315 | + char flv_header[13]; |
317 | 316 | ||
318 | // send flv header | 317 | // send flv header |
319 | - if ((ret = ffd.read_header(&flv_header, &flv_size)) != ERROR_SUCCESS) { | 318 | + if ((ret = ffd.read_header_ext(flv_header)) != ERROR_SUCCESS) { |
320 | return ret; | 319 | return ret; |
321 | } | 320 | } |
322 | - SrsAutoFree(char, flv_header); | ||
323 | 321 | ||
324 | // save sequence header, send later | 322 | // save sequence header, send later |
325 | char* sh_data = NULL; | 323 | char* sh_data = NULL; |
@@ -328,7 +326,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | @@ -328,7 +326,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | ||
328 | if (true) { | 326 | if (true) { |
329 | // send sequence header | 327 | // send sequence header |
330 | int64_t start = 0; | 328 | int64_t start = 0; |
331 | - if ((ret = ffd.read_sequence_header(&start, &sh_size)) != ERROR_SUCCESS) { | 329 | + if ((ret = ffd.read_sequence_header_summary(&start, &sh_size)) != ERROR_SUCCESS) { |
332 | return ret; | 330 | return ret; |
333 | } | 331 | } |
334 | if (sh_size <= 0) { | 332 | if (sh_size <= 0) { |
@@ -350,7 +348,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | @@ -350,7 +348,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | ||
350 | std::stringstream ss; | 348 | std::stringstream ss; |
351 | 349 | ||
352 | res_status_line(ss)->res_content_type_flv(ss) | 350 | res_status_line(ss)->res_content_type_flv(ss) |
353 | - ->res_content_length(ss, (int)(flv_size + sh_size + left)); | 351 | + ->res_content_length(ss, (int)(sizeof(flv_header) + sh_size + left)); |
354 | 352 | ||
355 | if (req->requires_crossdomain()) { | 353 | if (req->requires_crossdomain()) { |
356 | res_enable_crossdomain(ss); | 354 | res_enable_crossdomain(ss); |
@@ -363,7 +361,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | @@ -363,7 +361,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string | ||
363 | return ret; | 361 | return ret; |
364 | } | 362 | } |
365 | 363 | ||
366 | - if (flv_size > 0 && (ret = skt->write(flv_header, flv_size, NULL)) != ERROR_SUCCESS) { | 364 | + if ((ret = skt->write(flv_header, sizeof(flv_header), NULL)) != ERROR_SUCCESS) { |
367 | return ret; | 365 | return ret; |
368 | } | 366 | } |
369 | if (sh_size > 0 && (ret = skt->write(sh_data, sh_size, NULL)) != ERROR_SUCCESS) { | 367 | if (sh_size > 0 && (ret = skt->write(sh_data, sh_size, NULL)) != ERROR_SUCCESS) { |
trunk/src/core/srs_core.hpp
100755 → 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 | -#ifndef SRS_CORE_HPP | ||
25 | -#define SRS_CORE_HPP | ||
26 | - | ||
27 | -/* | ||
28 | -#include <srs_core.hpp> | ||
29 | -*/ | ||
30 | - | ||
31 | -// current release version | ||
32 | -#define VERSION_MAJOR "0" | ||
33 | -#define VERSION_MINOR "9" | ||
34 | -#define VERSION_REVISION "146" | ||
35 | -#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | ||
36 | -// server info. | ||
37 | -#define RTMP_SIG_SRS_KEY "SRS" | ||
38 | -#define RTMP_SIG_SRS_ROLE "origin/edge server" | ||
39 | -#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)" | ||
40 | -#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" | ||
41 | -#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT | ||
42 | -#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" | ||
43 | -#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" | ||
44 | -#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" | ||
45 | -#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin" | ||
46 | -#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjie.zhao" | ||
47 | -#define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt" | ||
48 | - | ||
49 | -/** | ||
50 | -* the core provides the common defined macros, utilities, | ||
51 | -* user must include the srs_core.hpp before any header, or maybe | ||
52 | -* build failed. | ||
53 | -*/ | ||
54 | - | ||
55 | -// for 32bit os, 2G big file limit for unistd io, | ||
56 | -// ie. read/write/lseek to use 64bits size for huge file. | ||
57 | -#ifndef _FILE_OFFSET_BITS | ||
58 | - #define _FILE_OFFSET_BITS 64 | ||
59 | -#endif | ||
60 | - | ||
61 | -// for int64_t print using PRId64 format. | ||
62 | -#ifndef __STDC_FORMAT_MACROS | ||
63 | - #define __STDC_FORMAT_MACROS | ||
64 | -#endif | ||
65 | -#include <inttypes.h> | ||
66 | - | ||
67 | -#include <assert.h> | ||
68 | -#define srs_assert(expression) assert(expression) | ||
69 | - | ||
70 | -#include <stddef.h> | ||
71 | -#include <sys/types.h> | ||
72 | - | ||
73 | -// generated by configure. | ||
74 | -#include <srs_auto_headers.hpp> | ||
75 | - | ||
76 | -// free the p and set to NULL. | ||
77 | -// p must be a T*. | ||
78 | -#define srs_freep(p) \ | ||
79 | - if (p) { \ | ||
80 | - delete p; \ | ||
81 | - p = NULL; \ | ||
82 | - } \ | ||
83 | - (void)0 | ||
84 | -// sometimes, the freepa is useless, | ||
85 | -// it's recomments to free each elem explicit. | ||
86 | -// so we remove the srs_freepa utility. | ||
87 | - | ||
88 | -/** | ||
89 | -* disable copy constructor of class | ||
90 | -*/ | ||
91 | -#define disable_default_copy(className)\ | ||
92 | - private:\ | ||
93 | - /** \ | ||
94 | - * disable the copy constructor and operator=, donot allow directly copy. \ | ||
95 | - */ \ | ||
96 | - className(const className&); \ | ||
97 | - className& operator= (const className&) | ||
98 | - | ||
99 | -#endif | 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 | +#ifndef SRS_CORE_HPP | ||
25 | +#define SRS_CORE_HPP | ||
26 | + | ||
27 | +/* | ||
28 | +#include <srs_core.hpp> | ||
29 | +*/ | ||
30 | + | ||
31 | +// current release version | ||
32 | +#define VERSION_MAJOR "0" | ||
33 | +#define VERSION_MINOR "9" | ||
34 | +#define VERSION_REVISION "147" | ||
35 | +#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | ||
36 | +// server info. | ||
37 | +#define RTMP_SIG_SRS_KEY "SRS" | ||
38 | +#define RTMP_SIG_SRS_ROLE "origin/edge server" | ||
39 | +#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)" | ||
40 | +#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" | ||
41 | +#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT | ||
42 | +#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" | ||
43 | +#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" | ||
44 | +#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" | ||
45 | +#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin" | ||
46 | +#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjie.zhao" | ||
47 | +#define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt" | ||
48 | + | ||
49 | +/** | ||
50 | +* the core provides the common defined macros, utilities, | ||
51 | +* user must include the srs_core.hpp before any header, or maybe | ||
52 | +* build failed. | ||
53 | +*/ | ||
54 | + | ||
55 | +// for 32bit os, 2G big file limit for unistd io, | ||
56 | +// ie. read/write/lseek to use 64bits size for huge file. | ||
57 | +#ifndef _FILE_OFFSET_BITS | ||
58 | + #define _FILE_OFFSET_BITS 64 | ||
59 | +#endif | ||
60 | + | ||
61 | +// for int64_t print using PRId64 format. | ||
62 | +#ifndef __STDC_FORMAT_MACROS | ||
63 | + #define __STDC_FORMAT_MACROS | ||
64 | +#endif | ||
65 | +#include <inttypes.h> | ||
66 | + | ||
67 | +#include <assert.h> | ||
68 | +#define srs_assert(expression) assert(expression) | ||
69 | + | ||
70 | +#include <stddef.h> | ||
71 | +#include <sys/types.h> | ||
72 | + | ||
73 | +// generated by configure. | ||
74 | +#include <srs_auto_headers.hpp> | ||
75 | + | ||
76 | +// free the p and set to NULL. | ||
77 | +// p must be a T*. | ||
78 | +#define srs_freep(p) \ | ||
79 | + if (p) { \ | ||
80 | + delete p; \ | ||
81 | + p = NULL; \ | ||
82 | + } \ | ||
83 | + (void)0 | ||
84 | +// sometimes, the freepa is useless, | ||
85 | +// it's recomments to free each elem explicit. | ||
86 | +// so we remove the srs_freepa utility. | ||
87 | + | ||
88 | +/** | ||
89 | +* disable copy constructor of class | ||
90 | +*/ | ||
91 | +#define disable_default_copy(className)\ | ||
92 | + private:\ | ||
93 | + /** \ | ||
94 | + * disable the copy constructor and operator=, donot allow directly copy. \ | ||
95 | + */ \ | ||
96 | + className(const className&); \ | ||
97 | + className& operator= (const className&) | ||
98 | + | ||
99 | +#endif |
@@ -119,8 +119,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -119,8 +119,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
119 | #define ERROR_SYSTEM_FILE_RENAME 429 | 119 | #define ERROR_SYSTEM_FILE_RENAME 429 |
120 | #define ERROR_SYSTEM_CREATE_PIPE 430 | 120 | #define ERROR_SYSTEM_CREATE_PIPE 430 |
121 | #define ERROR_SYSTEM_FILE_SEEK 431 | 121 | #define ERROR_SYSTEM_FILE_SEEK 431 |
122 | -#define ERROR_SYSTEM_FLV_HEADER 432 | ||
123 | -#define ERROR_SYSTEM_IO_INVALID 433 | 122 | +#define ERROR_SYSTEM_IO_INVALID 432 |
124 | 123 | ||
125 | // see librtmp. | 124 | // see librtmp. |
126 | // failed when open ssl create the dh | 125 | // failed when open ssl create the dh |
@@ -189,12 +188,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -189,12 +188,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
189 | #define ERROR_HTTP_FLV_SEQUENCE_HEADER 806 | 188 | #define ERROR_HTTP_FLV_SEQUENCE_HEADER 806 |
190 | #define ERROR_HTTP_FLV_OFFSET_OVERFLOW 807 | 189 | #define ERROR_HTTP_FLV_OFFSET_OVERFLOW 807 |
191 | 190 | ||
191 | +#define ERROR_KERNEL_FLV_HEADER 900 | ||
192 | +#define ERROR_KERNEL_FLV_STREAM_CLOSED 901 | ||
193 | + | ||
192 | // system control message, | 194 | // system control message, |
193 | // not an error, but special control logic. | 195 | // not an error, but special control logic. |
194 | // sys ctl: rtmp close stream, support replay. | 196 | // sys ctl: rtmp close stream, support replay. |
195 | -#define ERROR_CONTROL_RTMP_CLOSE 900 | 197 | +#define ERROR_CONTROL_RTMP_CLOSE 2000 |
196 | // FMLE stop publish and republish. | 198 | // FMLE stop publish and republish. |
197 | -#define ERROR_CONTROL_REPUBLISH 901 | 199 | +#define ERROR_CONTROL_REPUBLISH 2001 |
198 | 200 | ||
199 | /** | 201 | /** |
200 | * whether the error code is an system control error. | 202 | * whether the error code is an system control error. |
@@ -53,6 +53,12 @@ int SrsFlvEncoder::initialize(SrsFileWriter* fs) | @@ -53,6 +53,12 @@ int SrsFlvEncoder::initialize(SrsFileWriter* fs) | ||
53 | { | 53 | { |
54 | int ret = ERROR_SUCCESS; | 54 | int ret = ERROR_SUCCESS; |
55 | 55 | ||
56 | + if (!fs->is_open()) { | ||
57 | + ret = ERROR_KERNEL_FLV_STREAM_CLOSED; | ||
58 | + srs_warn("stream is not open for decoder. ret=%d", ret); | ||
59 | + return ret; | ||
60 | + } | ||
61 | + | ||
56 | _fs = fs; | 62 | _fs = fs; |
57 | 63 | ||
58 | return ret; | 64 | return ret; |
@@ -92,7 +98,7 @@ int SrsFlvEncoder::write_header(char flv_header[9]) | @@ -92,7 +98,7 @@ int SrsFlvEncoder::write_header(char flv_header[9]) | ||
92 | return ret; | 98 | return ret; |
93 | } | 99 | } |
94 | 100 | ||
95 | - char pts[] = { 0x00, 0x00, 0x00, 0x00 }; | 101 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 }; |
96 | if ((ret = _fs->write(pts, 4, NULL)) != ERROR_SUCCESS) { | 102 | if ((ret = _fs->write(pts, 4, NULL)) != ERROR_SUCCESS) { |
97 | return ret; | 103 | return ret; |
98 | } | 104 | } |
@@ -104,6 +110,7 @@ int SrsFlvEncoder::write_metadata(char* data, int size) | @@ -104,6 +110,7 @@ int SrsFlvEncoder::write_metadata(char* data, int size) | ||
104 | { | 110 | { |
105 | int ret = ERROR_SUCCESS; | 111 | int ret = ERROR_SUCCESS; |
106 | 112 | ||
113 | + // 11 bytes tag header | ||
107 | static char tag_header[] = { | 114 | static char tag_header[] = { |
108 | (char)18, // TagType UB [5], 18 = script data | 115 | (char)18, // TagType UB [5], 18 = script data |
109 | (char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message. | 116 | (char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message. |
@@ -240,6 +247,12 @@ int SrsFlvDecoder::initialize(SrsFileReader* fs) | @@ -240,6 +247,12 @@ int SrsFlvDecoder::initialize(SrsFileReader* fs) | ||
240 | { | 247 | { |
241 | int ret = ERROR_SUCCESS; | 248 | int ret = ERROR_SUCCESS; |
242 | 249 | ||
250 | + if (!fs->is_open()) { | ||
251 | + ret = ERROR_KERNEL_FLV_STREAM_CLOSED; | ||
252 | + srs_warn("stream is not open for decoder. ret=%d", ret); | ||
253 | + return ret; | ||
254 | + } | ||
255 | + | ||
243 | _fs = fs; | 256 | _fs = fs; |
244 | 257 | ||
245 | return ret; | 258 | return ret; |
@@ -255,7 +268,7 @@ int SrsFlvDecoder::read_header(char header[9]) | @@ -255,7 +268,7 @@ int SrsFlvDecoder::read_header(char header[9]) | ||
255 | 268 | ||
256 | char* h = header; | 269 | char* h = header; |
257 | if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { | 270 | if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { |
258 | - ret = ERROR_SYSTEM_FLV_HEADER; | 271 | + ret = ERROR_KERNEL_FLV_HEADER; |
259 | srs_warn("flv header must start with FLV. ret=%d", ret); | 272 | srs_warn("flv header must start with FLV. ret=%d", ret); |
260 | return ret; | 273 | return ret; |
261 | } | 274 | } |
@@ -345,35 +358,37 @@ int SrsFlvVodStreamDecoder::initialize(SrsFileReader* fs) | @@ -345,35 +358,37 @@ int SrsFlvVodStreamDecoder::initialize(SrsFileReader* fs) | ||
345 | { | 358 | { |
346 | int ret = ERROR_SUCCESS; | 359 | int ret = ERROR_SUCCESS; |
347 | 360 | ||
361 | + if (!fs->is_open()) { | ||
362 | + ret = ERROR_KERNEL_FLV_STREAM_CLOSED; | ||
363 | + srs_warn("stream is not open for decoder. ret=%d", ret); | ||
364 | + return ret; | ||
365 | + } | ||
366 | + | ||
348 | _fs = fs; | 367 | _fs = fs; |
349 | 368 | ||
350 | return ret; | 369 | return ret; |
351 | } | 370 | } |
352 | 371 | ||
353 | -int SrsFlvVodStreamDecoder::read_header(char** pdata, int* psize) | 372 | +int SrsFlvVodStreamDecoder::read_header_ext(char header[13]) |
354 | { | 373 | { |
355 | - *pdata = NULL; | ||
356 | - *psize = 0; | ||
357 | - | ||
358 | int ret = ERROR_SUCCESS; | 374 | int ret = ERROR_SUCCESS; |
359 | 375 | ||
360 | srs_assert(_fs); | 376 | srs_assert(_fs); |
361 | 377 | ||
378 | + // @remark, always false, for sizeof(char[13]) equals to sizeof(char*) | ||
379 | + //srs_assert(13 == sizeof(header)); | ||
380 | + | ||
362 | // 9bytes header and 4bytes first previous-tag-size | 381 | // 9bytes header and 4bytes first previous-tag-size |
363 | int size = 13; | 382 | int size = 13; |
364 | - char* buf = new char[size]; | ||
365 | 383 | ||
366 | - if ((ret = _fs->read(buf, size, NULL)) != ERROR_SUCCESS) { | 384 | + if ((ret = _fs->read(header, size, NULL)) != ERROR_SUCCESS) { |
367 | return ret; | 385 | return ret; |
368 | } | 386 | } |
369 | 387 | ||
370 | - *pdata = buf; | ||
371 | - *psize = size; | ||
372 | - | ||
373 | return ret; | 388 | return ret; |
374 | } | 389 | } |
375 | 390 | ||
376 | -int SrsFlvVodStreamDecoder::read_sequence_header(int64_t* pstart, int* psize) | 391 | +int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* psize) |
377 | { | 392 | { |
378 | *pstart = 0; | 393 | *pstart = 0; |
379 | *psize = 0; | 394 | *psize = 0; |
@@ -66,7 +66,7 @@ public: | @@ -66,7 +66,7 @@ public: | ||
66 | virtual int write_header(char flv_header[9]); | 66 | virtual int write_header(char flv_header[9]); |
67 | /** | 67 | /** |
68 | * write flv metadata. | 68 | * write flv metadata. |
69 | - * serialize from: | 69 | + * @param data, the amf0 metadata which serialize from: |
70 | * AMF0 string: onMetaData, | 70 | * AMF0 string: onMetaData, |
71 | * AMF0 object: the metadata object. | 71 | * AMF0 object: the metadata object. |
72 | */ | 72 | */ |
@@ -76,6 +76,7 @@ public: | @@ -76,6 +76,7 @@ public: | ||
76 | */ | 76 | */ |
77 | virtual int write_audio(int64_t timestamp, char* data, int size); | 77 | virtual int write_audio(int64_t timestamp, char* data, int size); |
78 | virtual int write_video(int64_t timestamp, char* data, int size); | 78 | virtual int write_video(int64_t timestamp, char* data, int size); |
79 | +public: | ||
79 | /** | 80 | /** |
80 | * get the tag size, | 81 | * get the tag size, |
81 | * including the tag header, body, and 4bytes previous tag size. | 82 | * including the tag header, body, and 4bytes previous tag size. |
@@ -134,13 +135,17 @@ public: | @@ -134,13 +135,17 @@ public: | ||
134 | virtual int initialize(SrsFileReader* fs); | 135 | virtual int initialize(SrsFileReader* fs); |
135 | public: | 136 | public: |
136 | /** | 137 | /** |
137 | - * read the flv header and size. | 138 | + * read the flv header and its size. |
139 | + * @param header, fill it 13bytes(9bytes header, 4bytes previous tag size). | ||
138 | */ | 140 | */ |
139 | - virtual int read_header(char** pdata, int* psize); | 141 | + virtual int read_header_ext(char header[13]); |
140 | /** | 142 | /** |
141 | - * read the sequence header and size. | 143 | + * read the sequence header tags offset and its size. |
144 | + * @param pstart, the start offset of sequence header. | ||
145 | + * @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size). | ||
146 | + * @remark we think the first audio/video is sequence header. | ||
142 | */ | 147 | */ |
143 | - virtual int read_sequence_header(int64_t* pstart, int* psize); | 148 | + virtual int read_sequence_header_summary(int64_t* pstart, int* psize); |
144 | public: | 149 | public: |
145 | /** | 150 | /** |
146 | * for start offset, seed to this position and response flv stream. | 151 | * for start offset, seed to this position and response flv stream. |
@@ -557,31 +557,6 @@ namespace srs | @@ -557,31 +557,6 @@ namespace srs | ||
557 | return bytes; | 557 | return bytes; |
558 | } | 558 | } |
559 | 559 | ||
560 | - /** | ||
561 | - * compare the memory in bytes. | ||
562 | - */ | ||
563 | - bool srs_bytes_equals(void* pa, void* pb, int size) | ||
564 | - { | ||
565 | - u_int8_t* a = (u_int8_t*)pa; | ||
566 | - u_int8_t* b = (u_int8_t*)pb; | ||
567 | - | ||
568 | - if (!a && !b) { | ||
569 | - return true; | ||
570 | - } | ||
571 | - | ||
572 | - if (!a || !b) { | ||
573 | - return false; | ||
574 | - } | ||
575 | - | ||
576 | - for(int i = 0; i < size; i++){ | ||
577 | - if(a[i] != b[i]){ | ||
578 | - return false; | ||
579 | - } | ||
580 | - } | ||
581 | - | ||
582 | - return true; | ||
583 | - } | ||
584 | - | ||
585 | c2s2::c2s2() | 560 | c2s2::c2s2() |
586 | { | 561 | { |
587 | srs_random_generate(random, 1504); | 562 | srs_random_generate(random, 1504); |
@@ -168,11 +168,6 @@ namespace srs | @@ -168,11 +168,6 @@ namespace srs | ||
168 | char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); | 168 | char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); |
169 | 169 | ||
170 | /** | 170 | /** |
171 | - * compare the memory in bytes. | ||
172 | - */ | ||
173 | - bool srs_bytes_equals(void* pa, void* pb, int size); | ||
174 | - | ||
175 | - /** | ||
176 | * c1s1 schema0 | 171 | * c1s1 schema0 |
177 | * time: 4bytes | 172 | * time: 4bytes |
178 | * version: 4bytes | 173 | * version: 4bytes |
@@ -126,3 +126,28 @@ string srs_generate_tc_url(string ip, string vhost, string app, string port) | @@ -126,3 +126,28 @@ string srs_generate_tc_url(string ip, string vhost, string app, string port) | ||
126 | 126 | ||
127 | return tcUrl; | 127 | return tcUrl; |
128 | } | 128 | } |
129 | + | ||
130 | +/** | ||
131 | +* compare the memory in bytes. | ||
132 | +*/ | ||
133 | +bool srs_bytes_equals(void* pa, void* pb, int size) | ||
134 | +{ | ||
135 | + u_int8_t* a = (u_int8_t*)pa; | ||
136 | + u_int8_t* b = (u_int8_t*)pb; | ||
137 | + | ||
138 | + if (!a && !b) { | ||
139 | + return true; | ||
140 | + } | ||
141 | + | ||
142 | + if (!a || !b) { | ||
143 | + return false; | ||
144 | + } | ||
145 | + | ||
146 | + for(int i = 0; i < size; i++){ | ||
147 | + if(a[i] != b[i]){ | ||
148 | + return false; | ||
149 | + } | ||
150 | + } | ||
151 | + | ||
152 | + return true; | ||
153 | +} |
@@ -58,4 +58,9 @@ extern void srs_random_generate(char* bytes, int size); | @@ -58,4 +58,9 @@ extern void srs_random_generate(char* bytes, int size); | ||
58 | // generate the tcUrl. | 58 | // generate the tcUrl. |
59 | extern std::string srs_generate_tc_url(std::string ip, std::string vhost, std::string app, std::string port); | 59 | extern std::string srs_generate_tc_url(std::string ip, std::string vhost, std::string app, std::string port); |
60 | 60 | ||
61 | +/** | ||
62 | +* compare the memory in bytes. | ||
63 | +*/ | ||
64 | +extern bool srs_bytes_equals(void* pa, void* pb, int size); | ||
65 | + | ||
61 | #endif | 66 | #endif |
@@ -27,93 +27,155 @@ using namespace std; | @@ -27,93 +27,155 @@ using namespace std; | ||
27 | #include <srs_kernel_error.hpp> | 27 | #include <srs_kernel_error.hpp> |
28 | #include <srs_kernel_codec.hpp> | 28 | #include <srs_kernel_codec.hpp> |
29 | #include <srs_kernel_flv.hpp> | 29 | #include <srs_kernel_flv.hpp> |
30 | +#include <srs_kernel_utility.hpp> | ||
31 | +#include <srs_protocol_utility.hpp> | ||
32 | + | ||
33 | +#define MAX_MOCK_DATA_SIZE 1024 * 1024 | ||
30 | 34 | ||
31 | MockSrsFileWriter::MockSrsFileWriter() | 35 | MockSrsFileWriter::MockSrsFileWriter() |
32 | { | 36 | { |
37 | + data = new char[MAX_MOCK_DATA_SIZE]; | ||
38 | + offset = -1; | ||
33 | } | 39 | } |
34 | 40 | ||
35 | MockSrsFileWriter::~MockSrsFileWriter() | 41 | MockSrsFileWriter::~MockSrsFileWriter() |
36 | { | 42 | { |
43 | + srs_freep(data); | ||
37 | } | 44 | } |
38 | 45 | ||
39 | -int MockSrsFileWriter::open(string file) | 46 | +int MockSrsFileWriter::open(string /*file*/) |
40 | { | 47 | { |
41 | int ret = ERROR_SUCCESS; | 48 | int ret = ERROR_SUCCESS; |
49 | + | ||
50 | + offset = 0; | ||
51 | + | ||
42 | return ret; | 52 | return ret; |
43 | } | 53 | } |
44 | 54 | ||
45 | void MockSrsFileWriter::close() | 55 | void MockSrsFileWriter::close() |
46 | { | 56 | { |
47 | - int ret = ERROR_SUCCESS; | ||
48 | - return; | 57 | + offset = 0; |
49 | } | 58 | } |
50 | 59 | ||
51 | bool MockSrsFileWriter::is_open() | 60 | bool MockSrsFileWriter::is_open() |
52 | { | 61 | { |
53 | - return true; | 62 | + return offset >= 0; |
54 | } | 63 | } |
55 | 64 | ||
56 | int64_t MockSrsFileWriter::tellg() | 65 | int64_t MockSrsFileWriter::tellg() |
57 | { | 66 | { |
58 | - return 0; | 67 | + return offset; |
59 | } | 68 | } |
60 | 69 | ||
61 | int MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) | 70 | int MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) |
62 | { | 71 | { |
63 | int ret = ERROR_SUCCESS; | 72 | int ret = ERROR_SUCCESS; |
73 | + | ||
74 | + int size = srs_min(MAX_MOCK_DATA_SIZE - offset, count); | ||
75 | + | ||
76 | + memcpy(data + offset, buf, size); | ||
77 | + | ||
78 | + if (pnwrite) { | ||
79 | + *pnwrite = size; | ||
80 | + } | ||
81 | + | ||
82 | + offset += size; | ||
83 | + | ||
64 | return ret; | 84 | return ret; |
65 | } | 85 | } |
66 | 86 | ||
87 | +void MockSrsFileWriter::mock_reset_offset() | ||
88 | +{ | ||
89 | + offset = 0; | ||
90 | +} | ||
91 | + | ||
67 | MockSrsFileReader::MockSrsFileReader() | 92 | MockSrsFileReader::MockSrsFileReader() |
68 | { | 93 | { |
94 | + data = new char[MAX_MOCK_DATA_SIZE]; | ||
95 | + size = 0; | ||
96 | + offset = -1; | ||
69 | } | 97 | } |
70 | 98 | ||
71 | MockSrsFileReader::~MockSrsFileReader() | 99 | MockSrsFileReader::~MockSrsFileReader() |
72 | { | 100 | { |
101 | + srs_freep(data); | ||
73 | } | 102 | } |
74 | 103 | ||
75 | -int MockSrsFileReader::open(string file) | 104 | +int MockSrsFileReader::open(string /*file*/) |
76 | { | 105 | { |
77 | int ret = ERROR_SUCCESS; | 106 | int ret = ERROR_SUCCESS; |
107 | + | ||
108 | + offset = 0; | ||
109 | + | ||
78 | return ret; | 110 | return ret; |
79 | } | 111 | } |
80 | 112 | ||
81 | void MockSrsFileReader::close() | 113 | void MockSrsFileReader::close() |
82 | { | 114 | { |
83 | - int ret = ERROR_SUCCESS; | ||
84 | - return; | 115 | + offset = 0; |
85 | } | 116 | } |
86 | 117 | ||
87 | bool MockSrsFileReader::is_open() | 118 | bool MockSrsFileReader::is_open() |
88 | { | 119 | { |
89 | - return true; | 120 | + return offset >= 0; |
90 | } | 121 | } |
91 | 122 | ||
92 | int64_t MockSrsFileReader::tellg() | 123 | int64_t MockSrsFileReader::tellg() |
93 | { | 124 | { |
94 | - return 0; | 125 | + return offset; |
95 | } | 126 | } |
96 | 127 | ||
97 | -void MockSrsFileReader::skip(int64_t size) | 128 | +void MockSrsFileReader::skip(int64_t _size) |
98 | { | 129 | { |
130 | + offset += _size; | ||
99 | } | 131 | } |
100 | 132 | ||
101 | -int64_t MockSrsFileReader::lseek(int64_t offset) | 133 | +int64_t MockSrsFileReader::lseek(int64_t _offset) |
102 | { | 134 | { |
135 | + offset = (int)_offset; | ||
103 | return offset; | 136 | return offset; |
104 | } | 137 | } |
105 | 138 | ||
106 | int64_t MockSrsFileReader::filesize() | 139 | int64_t MockSrsFileReader::filesize() |
107 | { | 140 | { |
108 | - return 0; | 141 | + return size; |
109 | } | 142 | } |
110 | 143 | ||
111 | int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread) | 144 | int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread) |
112 | { | 145 | { |
113 | int ret = ERROR_SUCCESS; | 146 | int ret = ERROR_SUCCESS; |
147 | + | ||
148 | + int s = srs_min(size - offset, (int)count); | ||
149 | + | ||
150 | + if (s <= 0) { | ||
151 | + return ret; | ||
152 | + } | ||
153 | + | ||
154 | + memcpy(buf, data + offset, s); | ||
155 | + | ||
156 | + if (pnread) { | ||
157 | + *pnread = s; | ||
158 | + } | ||
159 | + | ||
160 | + offset += s; | ||
161 | + | ||
114 | return ret; | 162 | return ret; |
115 | } | 163 | } |
116 | 164 | ||
165 | +void MockSrsFileReader::mock_append_data(const char* _data, int _size) | ||
166 | +{ | ||
167 | + int s = srs_min(MAX_MOCK_DATA_SIZE - offset, _size); | ||
168 | + memcpy(data + offset, _data, s); | ||
169 | + | ||
170 | + offset += s; | ||
171 | + size += s; | ||
172 | +} | ||
173 | + | ||
174 | +void MockSrsFileReader::mock_reset_offset() | ||
175 | +{ | ||
176 | + offset = 0; | ||
177 | +} | ||
178 | + | ||
117 | VOID TEST(KernelCodecTest, IsKeyFrame) | 179 | VOID TEST(KernelCodecTest, IsKeyFrame) |
118 | { | 180 | { |
119 | int8_t data; | 181 | int8_t data; |
@@ -196,9 +258,431 @@ VOID TEST(KernelCodecTest, IsAudioSequenceHeader) | @@ -196,9 +258,431 @@ VOID TEST(KernelCodecTest, IsAudioSequenceHeader) | ||
196 | EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2)); | 258 | EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2)); |
197 | } | 259 | } |
198 | 260 | ||
199 | -VOID TEST(KernelFlvTest, IsAudioSequenceHeader) | 261 | +VOID TEST(KernelFlvTest, FlvEncoderStreamClosed) |
262 | +{ | ||
263 | + MockSrsFileWriter fs; | ||
264 | + SrsFlvEncoder enc; | ||
265 | + ASSERT_TRUE(ERROR_SUCCESS != enc.initialize(&fs)); | ||
266 | +} | ||
267 | + | ||
268 | +VOID TEST(KernelFlvTest, FlvEncoderWriteHeader) | ||
269 | +{ | ||
270 | + MockSrsFileWriter fs; | ||
271 | + SrsFlvEncoder enc; | ||
272 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
273 | + ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs)); | ||
274 | + | ||
275 | + // write header, 9bytes | ||
276 | + char flv_header[] = { | ||
277 | + 'F', 'L', 'V', // Signatures "FLV" | ||
278 | + (char)0x01, // File version (for example, 0x01 for FLV version 1) | ||
279 | + (char)0x00, // 4, audio; 1, video; 5 audio+video. | ||
280 | + (char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes | ||
281 | + }; | ||
282 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 }; | ||
283 | + | ||
284 | + EXPECT_TRUE(ERROR_SUCCESS == enc.write_header()); | ||
285 | + ASSERT_TRUE(9 + 4 == fs.offset); | ||
286 | + | ||
287 | + EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data, 9)); | ||
288 | + EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4)); | ||
289 | + | ||
290 | + // customer header | ||
291 | + flv_header[3] = 0xF0; | ||
292 | + flv_header[4] = 0xF1; | ||
293 | + flv_header[5] = 0x01; | ||
294 | + | ||
295 | + fs.mock_reset_offset(); | ||
296 | + | ||
297 | + EXPECT_TRUE(ERROR_SUCCESS == enc.write_header(flv_header)); | ||
298 | + ASSERT_TRUE(9 + 4 == fs.offset); | ||
299 | + | ||
300 | + EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data, 9)); | ||
301 | + EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4)); | ||
302 | +} | ||
303 | + | ||
304 | +VOID TEST(KernelFlvTest, FlvEncoderWriteMetadata) | ||
305 | +{ | ||
306 | + MockSrsFileWriter fs; | ||
307 | + EXPECT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
308 | + SrsFlvEncoder enc; | ||
309 | + ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs)); | ||
310 | + | ||
311 | + // 11 bytes tag header | ||
312 | + char tag_header[] = { | ||
313 | + (char)18, // TagType UB [5], 18 = script data | ||
314 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
315 | + (char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
316 | + (char)0x00, // TimestampExtended UI8 | ||
317 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
318 | + }; | ||
319 | + char md[] = { | ||
320 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
321 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
322 | + }; | ||
323 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
324 | + | ||
325 | + ASSERT_TRUE(ERROR_SUCCESS == enc.write_metadata(md, 8)); | ||
326 | + ASSERT_TRUE(11 + 8 + 4 == fs.offset); | ||
327 | + | ||
328 | + EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11)); | ||
329 | + EXPECT_TRUE(srs_bytes_equals(md, fs.data + 11, 8)); | ||
330 | + EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled. | ||
331 | + EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 19, 4)); | ||
332 | +} | ||
333 | + | ||
334 | +VOID TEST(KernelFlvTest, FlvEncoderWriteAudio) | ||
335 | +{ | ||
336 | + MockSrsFileWriter fs; | ||
337 | + SrsFlvEncoder enc; | ||
338 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
339 | + ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs)); | ||
340 | + | ||
341 | + // 11bytes tag header | ||
342 | + char tag_header[] = { | ||
343 | + (char)8, // TagType UB [5], 8 = audio | ||
344 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
345 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
346 | + (char)0x00, // TimestampExtended UI8 | ||
347 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
348 | + }; | ||
349 | + char audio[] = { | ||
350 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
351 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
352 | + }; | ||
353 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
354 | + | ||
355 | + ASSERT_TRUE(ERROR_SUCCESS == enc.write_audio(0x30, audio, 8)); | ||
356 | + ASSERT_TRUE(11 + 8 + 4 == fs.offset); | ||
357 | + | ||
358 | + EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11)); | ||
359 | + EXPECT_TRUE(srs_bytes_equals(audio, fs.data + 11, 8)); | ||
360 | + EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled. | ||
361 | + EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4)); | ||
362 | +} | ||
363 | + | ||
364 | +VOID TEST(KernelFlvTest, FlvEncoderWriteVideo) | ||
200 | { | 365 | { |
201 | MockSrsFileWriter fs; | 366 | MockSrsFileWriter fs; |
202 | SrsFlvEncoder enc; | 367 | SrsFlvEncoder enc; |
368 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
203 | ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs)); | 369 | ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs)); |
370 | + | ||
371 | + // 11bytes tag header | ||
372 | + char tag_header[] = { | ||
373 | + (char)9, // TagType UB [5], 9 = video | ||
374 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
375 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
376 | + (char)0x00, // TimestampExtended UI8 | ||
377 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
378 | + }; | ||
379 | + char video[] = { | ||
380 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
381 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
382 | + }; | ||
383 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
384 | + | ||
385 | + ASSERT_TRUE(ERROR_SUCCESS == enc.write_video(0x30, video, 8)); | ||
386 | + ASSERT_TRUE(11 + 8 + 4 == fs.offset); | ||
387 | + | ||
388 | + EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11)); | ||
389 | + EXPECT_TRUE(srs_bytes_equals(video, fs.data + 11, 8)); | ||
390 | + EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled. | ||
391 | + EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4)); | ||
392 | +} | ||
393 | + | ||
394 | +VOID TEST(KernelFlvTest, FlvEncoderSizeTag) | ||
395 | +{ | ||
396 | + EXPECT_EQ(11+4+10, SrsFlvEncoder::size_tag(10)); | ||
397 | + EXPECT_EQ(11+4+0, SrsFlvEncoder::size_tag(0)); | ||
398 | +} | ||
399 | + | ||
400 | +VOID TEST(KernelFlvTest, FlvDecoderStreamClosed) | ||
401 | +{ | ||
402 | + MockSrsFileReader fs; | ||
403 | + SrsFlvDecoder dec; | ||
404 | + ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs)); | ||
405 | +} | ||
406 | + | ||
407 | +VOID TEST(KernelFlvTest, FlvDecoderHeader) | ||
408 | +{ | ||
409 | + MockSrsFileReader fs; | ||
410 | + SrsFlvDecoder dec; | ||
411 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
412 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
413 | + | ||
414 | + // 9bytes | ||
415 | + char flv_header[] = { | ||
416 | + 'F', 'L', 'V', // Signatures "FLV" | ||
417 | + (char)0x01, // File version (for example, 0x01 for FLV version 1) | ||
418 | + (char)0x00, // 4, audio; 1, video; 5 audio+video. | ||
419 | + (char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes | ||
420 | + }; | ||
421 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 }; | ||
422 | + fs.mock_append_data(flv_header, 9); | ||
423 | + fs.mock_append_data(pts, 4); | ||
424 | + | ||
425 | + char data[1024]; | ||
426 | + fs.mock_reset_offset(); | ||
427 | + | ||
428 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_header(data)); | ||
429 | + EXPECT_TRUE(srs_bytes_equals(flv_header, data, 9)); | ||
430 | + | ||
431 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data)); | ||
432 | + EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); | ||
433 | +} | ||
434 | + | ||
435 | +VOID TEST(KernelFlvTest, FlvDecoderMetadata) | ||
436 | +{ | ||
437 | + MockSrsFileReader fs; | ||
438 | + SrsFlvDecoder dec; | ||
439 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
440 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
441 | + | ||
442 | + // 11 bytes tag header | ||
443 | + char tag_header[] = { | ||
444 | + (char)18, // TagType UB [5], 18 = script data | ||
445 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
446 | + (char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
447 | + (char)0x00, // TimestampExtended UI8 | ||
448 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
449 | + }; | ||
450 | + char md[] = { | ||
451 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
452 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
453 | + }; | ||
454 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
455 | + fs.mock_append_data(tag_header, 11); | ||
456 | + fs.mock_append_data(md, 8); | ||
457 | + fs.mock_append_data(pts, 4); | ||
458 | + | ||
459 | + char type = 0; | ||
460 | + int32_t size = 0; | ||
461 | + u_int32_t time = 0; | ||
462 | + char data[1024]; | ||
463 | + fs.mock_reset_offset(); | ||
464 | + | ||
465 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_header(&type, &size, &time)); | ||
466 | + EXPECT_TRUE(18 == type); | ||
467 | + EXPECT_TRUE(8 == size); | ||
468 | + EXPECT_TRUE(0 == time); | ||
469 | + | ||
470 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_data(data, size)); | ||
471 | + EXPECT_TRUE(srs_bytes_equals(md, data, 8)); | ||
472 | + | ||
473 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data)); | ||
474 | + EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); | ||
475 | +} | ||
476 | + | ||
477 | +VOID TEST(KernelFlvTest, FlvDecoderAudio) | ||
478 | +{ | ||
479 | + MockSrsFileReader fs; | ||
480 | + SrsFlvDecoder dec; | ||
481 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
482 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
483 | + | ||
484 | + // 11bytes tag header | ||
485 | + char tag_header[] = { | ||
486 | + (char)8, // TagType UB [5], 8 = audio | ||
487 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
488 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
489 | + (char)0x00, // TimestampExtended UI8 | ||
490 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
491 | + }; | ||
492 | + char audio[] = { | ||
493 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
494 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
495 | + }; | ||
496 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
497 | + fs.mock_append_data(tag_header, 11); | ||
498 | + fs.mock_append_data(audio, 8); | ||
499 | + fs.mock_append_data(pts, 4); | ||
500 | + | ||
501 | + char type = 0; | ||
502 | + int32_t size = 0; | ||
503 | + u_int32_t time = 0; | ||
504 | + char data[1024]; | ||
505 | + fs.mock_reset_offset(); | ||
506 | + | ||
507 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_header(&type, &size, &time)); | ||
508 | + EXPECT_TRUE(8 == type); | ||
509 | + EXPECT_TRUE(8 == size); | ||
510 | + EXPECT_TRUE(0x30 == time); | ||
511 | + | ||
512 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_data(data, size)); | ||
513 | + EXPECT_TRUE(srs_bytes_equals(audio, data, 8)); | ||
514 | + | ||
515 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data)); | ||
516 | + EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); | ||
517 | +} | ||
518 | + | ||
519 | +VOID TEST(KernelFlvTest, FlvDecoderVideo) | ||
520 | +{ | ||
521 | + MockSrsFileReader fs; | ||
522 | + SrsFlvDecoder dec; | ||
523 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
524 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
525 | + | ||
526 | + // 11bytes tag header | ||
527 | + char tag_header[] = { | ||
528 | + (char)9, // TagType UB [5], 9 = video | ||
529 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
530 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
531 | + (char)0x00, // TimestampExtended UI8 | ||
532 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
533 | + }; | ||
534 | + char video[] = { | ||
535 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
536 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
537 | + }; | ||
538 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
539 | + fs.mock_append_data(tag_header, 11); | ||
540 | + fs.mock_append_data(video, 8); | ||
541 | + fs.mock_append_data(pts, 4); | ||
542 | + | ||
543 | + char type = 0; | ||
544 | + int32_t size = 0; | ||
545 | + u_int32_t time = 0; | ||
546 | + char data[1024]; | ||
547 | + fs.mock_reset_offset(); | ||
548 | + | ||
549 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_header(&type, &size, &time)); | ||
550 | + EXPECT_TRUE(9 == type); | ||
551 | + EXPECT_TRUE(8 == size); | ||
552 | + EXPECT_TRUE(0x30 == time); | ||
553 | + | ||
554 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_data(data, size)); | ||
555 | + EXPECT_TRUE(srs_bytes_equals(video, data, 8)); | ||
556 | + | ||
557 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data)); | ||
558 | + EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); | ||
559 | +} | ||
560 | + | ||
561 | +VOID TEST(KernelFlvTest, FlvVSDecoderStreamClosed) | ||
562 | +{ | ||
563 | + MockSrsFileReader fs; | ||
564 | + SrsFlvVodStreamDecoder dec; | ||
565 | + ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs)); | ||
566 | +} | ||
567 | + | ||
568 | +VOID TEST(KernelFlvTest, FlvVSDecoderHeader) | ||
569 | +{ | ||
570 | + MockSrsFileReader fs; | ||
571 | + SrsFlvVodStreamDecoder dec; | ||
572 | + | ||
573 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
574 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
575 | + | ||
576 | + // 9bytes | ||
577 | + char flv_header[] = { | ||
578 | + 'F', 'L', 'V', // Signatures "FLV" | ||
579 | + (char)0x01, // File version (for example, 0x01 for FLV version 1) | ||
580 | + (char)0x00, // 4, audio; 1, video; 5 audio+video. | ||
581 | + (char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes | ||
582 | + }; | ||
583 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 }; | ||
584 | + fs.mock_append_data(flv_header, 9); | ||
585 | + fs.mock_append_data(pts, 4); | ||
586 | + | ||
587 | + char data[1024]; | ||
588 | + fs.mock_reset_offset(); | ||
589 | + | ||
590 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_header_ext(data)); | ||
591 | + EXPECT_TRUE(srs_bytes_equals(flv_header, data, 9)); | ||
592 | +} | ||
593 | + | ||
594 | +VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader) | ||
595 | +{ | ||
596 | + MockSrsFileReader fs; | ||
597 | + SrsFlvVodStreamDecoder dec; | ||
598 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
599 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
600 | + | ||
601 | + if (true) { | ||
602 | + // 11 bytes tag header | ||
603 | + char tag_header[] = { | ||
604 | + (char)18, // TagType UB [5], 18 = script data | ||
605 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
606 | + (char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
607 | + (char)0x00, // TimestampExtended UI8 | ||
608 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
609 | + }; | ||
610 | + char md[] = { | ||
611 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
612 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
613 | + }; | ||
614 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
615 | + fs.mock_append_data(tag_header, 11); | ||
616 | + fs.mock_append_data(md, 8); | ||
617 | + fs.mock_append_data(pts, 4); | ||
618 | + } | ||
619 | + if (true) { | ||
620 | + // 11bytes tag header | ||
621 | + char tag_header[] = { | ||
622 | + (char)8, // TagType UB [5], 8 = audio | ||
623 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
624 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
625 | + (char)0x00, // TimestampExtended UI8 | ||
626 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
627 | + }; | ||
628 | + char audio[] = { | ||
629 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
630 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
631 | + }; | ||
632 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
633 | + fs.mock_append_data(tag_header, 11); | ||
634 | + fs.mock_append_data(audio, 8); | ||
635 | + fs.mock_append_data(pts, 4); | ||
636 | + } | ||
637 | + if (true) { | ||
638 | + // 11bytes tag header | ||
639 | + char tag_header[] = { | ||
640 | + (char)9, // TagType UB [5], 9 = video | ||
641 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
642 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
643 | + (char)0x00, // TimestampExtended UI8 | ||
644 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
645 | + }; | ||
646 | + char video[] = { | ||
647 | + (char)0x01, (char)0x02, (char)0x03, (char)0x04, | ||
648 | + (char)0x04, (char)0x03, (char)0x02, (char)0x01 | ||
649 | + }; | ||
650 | + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; | ||
651 | + fs.mock_append_data(tag_header, 11); | ||
652 | + fs.mock_append_data(video, 8); | ||
653 | + fs.mock_append_data(pts, 4); | ||
654 | + } | ||
655 | + | ||
656 | + fs.mock_reset_offset(); | ||
657 | + | ||
658 | + int64_t start = 0; | ||
659 | + int size = 0; | ||
660 | + EXPECT_TRUE(ERROR_SUCCESS == dec.read_sequence_header_summary(&start, &size)); | ||
661 | + EXPECT_TRUE(23 == start); | ||
662 | + EXPECT_TRUE(46 == size); | ||
663 | +} | ||
664 | + | ||
665 | +VOID TEST(KernelFlvTest, FlvVSDecoderSeek) | ||
666 | +{ | ||
667 | + MockSrsFileReader fs; | ||
668 | + SrsFlvVodStreamDecoder dec; | ||
669 | + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); | ||
670 | + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); | ||
671 | + | ||
672 | + // 11bytes tag header | ||
673 | + char tag_header[] = { | ||
674 | + (char)8, // TagType UB [5], 8 = audio | ||
675 | + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. | ||
676 | + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. | ||
677 | + (char)0x00, // TimestampExtended UI8 | ||
678 | + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. | ||
679 | + }; | ||
680 | + fs.mock_append_data(tag_header, 11); | ||
681 | + EXPECT_TRUE(11 == fs.offset); | ||
682 | + | ||
683 | + EXPECT_TRUE(ERROR_SUCCESS == dec.lseek(0)); | ||
684 | + EXPECT_TRUE(0 == fs.offset); | ||
685 | + | ||
686 | + EXPECT_TRUE(ERROR_SUCCESS == dec.lseek(5)); | ||
687 | + EXPECT_TRUE(5 == fs.offset); | ||
204 | } | 688 | } |
@@ -35,6 +35,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -35,6 +35,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
35 | class MockSrsFileWriter : public SrsFileWriter | 35 | class MockSrsFileWriter : public SrsFileWriter |
36 | { | 36 | { |
37 | public: | 37 | public: |
38 | + char* data; | ||
39 | + int offset; | ||
40 | +public: | ||
38 | MockSrsFileWriter(); | 41 | MockSrsFileWriter(); |
39 | virtual ~MockSrsFileWriter(); | 42 | virtual ~MockSrsFileWriter(); |
40 | public: | 43 | public: |
@@ -45,11 +48,18 @@ public: | @@ -45,11 +48,18 @@ public: | ||
45 | virtual int64_t tellg(); | 48 | virtual int64_t tellg(); |
46 | public: | 49 | public: |
47 | virtual int write(void* buf, size_t count, ssize_t* pnwrite); | 50 | virtual int write(void* buf, size_t count, ssize_t* pnwrite); |
51 | +// for mock | ||
52 | +public: | ||
53 | + void mock_reset_offset(); | ||
48 | }; | 54 | }; |
49 | 55 | ||
50 | class MockSrsFileReader : public SrsFileReader | 56 | class MockSrsFileReader : public SrsFileReader |
51 | { | 57 | { |
52 | public: | 58 | public: |
59 | + char* data; | ||
60 | + int size; | ||
61 | + int offset; | ||
62 | +public: | ||
53 | MockSrsFileReader(); | 63 | MockSrsFileReader(); |
54 | virtual ~MockSrsFileReader(); | 64 | virtual ~MockSrsFileReader(); |
55 | public: | 65 | public: |
@@ -63,6 +73,11 @@ public: | @@ -63,6 +73,11 @@ public: | ||
63 | virtual int64_t filesize(); | 73 | virtual int64_t filesize(); |
64 | public: | 74 | public: |
65 | virtual int read(void* buf, size_t count, ssize_t* pnread); | 75 | virtual int read(void* buf, size_t count, ssize_t* pnread); |
76 | +// for mock | ||
77 | +public: | ||
78 | + // append data to current offset, modify the offset and size. | ||
79 | + void mock_append_data(const char* _data, int _size); | ||
80 | + void mock_reset_offset(); | ||
66 | }; | 81 | }; |
67 | 82 | ||
68 | #endif | 83 | #endif |
-
请 注册 或 登录 后发表评论