winlin

complete the normal kernel flv utest. 0.9.147

@@ -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) {
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