winlin

fix chunk header parse bug, add utest for basic/message header

@@ -868,6 +868,50 @@ int SrsProtocol::recv_interlaced_message(SrsMessage** pmsg) @@ -868,6 +868,50 @@ int SrsProtocol::recv_interlaced_message(SrsMessage** pmsg)
868 return ret; 868 return ret;
869 } 869 }
870 870
  871 +/**
  872 +* 6.1.1. Chunk Basic Header
  873 +* The Chunk Basic Header encodes the chunk stream ID and the chunk
  874 +* type(represented by fmt field in the figure below). Chunk type
  875 +* determines the format of the encoded message header. Chunk Basic
  876 +* Header field may be 1, 2, or 3 bytes, depending on the chunk stream
  877 +* ID.
  878 +*
  879 +* The bits 0–5 (least significant) in the chunk basic header represent
  880 +* the chunk stream ID.
  881 +*
  882 +* Chunk stream IDs 2-63 can be encoded in the 1-byte version of this
  883 +* field.
  884 +* 0 1 2 3 4 5 6 7
  885 +* +-+-+-+-+-+-+-+-+
  886 +* |fmt| cs id |
  887 +* +-+-+-+-+-+-+-+-+
  888 +* Figure 6 Chunk basic header 1
  889 +*
  890 +* Chunk stream IDs 64-319 can be encoded in the 2-byte version of this
  891 +* field. ID is computed as (the second byte + 64).
  892 +* 0 1
  893 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  894 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  895 +* |fmt| 0 | cs id - 64 |
  896 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  897 +* Figure 7 Chunk basic header 2
  898 +*
  899 +* Chunk stream IDs 64-65599 can be encoded in the 3-byte version of
  900 +* this field. ID is computed as ((the third byte)*256 + the second byte
  901 +* + 64).
  902 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
  903 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  904 +* |fmt| 1 | cs id - 64 |
  905 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  906 +* Figure 8 Chunk basic header 3
  907 +*
  908 +* cs id: 6 bits
  909 +* fmt: 2 bits
  910 +* cs id - 64: 8 or 16 bits
  911 +*
  912 +* Chunk stream IDs with values 64-319 could be represented by both 2-
  913 +* byte version and 3-byte version of this field.
  914 +*/
871 int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size) 915 int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size)
872 { 916 {
873 int ret = ERROR_SUCCESS; 917 int ret = ERROR_SUCCESS;
@@ -886,11 +930,13 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size) @@ -886,11 +930,13 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size)
886 cid = *p & 0x3f; 930 cid = *p & 0x3f;
887 bh_size = 1; 931 bh_size = 1;
888 932
  933 + // 2-63, 1B chunk header
889 if (cid > 1) { 934 if (cid > 1) {
890 srs_verbose("%dbytes basic header parsed. fmt=%d, cid=%d", bh_size, fmt, cid); 935 srs_verbose("%dbytes basic header parsed. fmt=%d, cid=%d", bh_size, fmt, cid);
891 return ret; 936 return ret;
892 } 937 }
893 938
  939 + // 64-319, 2B chunk header
894 if (cid == 0) { 940 if (cid == 0) {
895 required_size = 2; 941 required_size = 2;
896 if ((ret = in_buffer->grow(skt, required_size)) != ERROR_SUCCESS) { 942 if ((ret = in_buffer->grow(skt, required_size)) != ERROR_SUCCESS) {
@@ -901,9 +947,10 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size) @@ -901,9 +947,10 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size)
901 } 947 }
902 948
903 cid = 64; 949 cid = 64;
904 - cid += *(++p); 950 + cid += (u_int8_t)*(++p);
905 bh_size = 2; 951 bh_size = 2;
906 srs_verbose("%dbytes basic header parsed. fmt=%d, cid=%d", bh_size, fmt, cid); 952 srs_verbose("%dbytes basic header parsed. fmt=%d, cid=%d", bh_size, fmt, cid);
  953 + // 64-65599, 3B chunk header
907 } else if (cid == 1) { 954 } else if (cid == 1) {
908 required_size = 3; 955 required_size = 3;
909 if ((ret = in_buffer->grow(skt, 3)) != ERROR_SUCCESS) { 956 if ((ret = in_buffer->grow(skt, 3)) != ERROR_SUCCESS) {
@@ -914,8 +961,8 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size) @@ -914,8 +961,8 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size)
914 } 961 }
915 962
916 cid = 64; 963 cid = 64;
917 - cid += *(++p);  
918 - cid += *(++p) * 256; 964 + cid += (u_int8_t)*(++p);
  965 + cid += ((u_int8_t)*(++p)) * 256;
919 bh_size = 3; 966 bh_size = 3;
920 srs_verbose("%dbytes basic header parsed. fmt=%d, cid=%d", bh_size, fmt, cid); 967 srs_verbose("%dbytes basic header parsed. fmt=%d, cid=%d", bh_size, fmt, cid);
921 } else { 968 } else {
@@ -926,6 +973,18 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size) @@ -926,6 +973,18 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid, int& bh_size)
926 return ret; 973 return ret;
927 } 974 }
928 975
  976 +/**
  977 +* parse the message header.
  978 +* 3bytes: timestamp delta, fmt=0,1,2
  979 +* 3bytes: payload length, fmt=0,1
  980 +* 1bytes: message type, fmt=0,1
  981 +* 4bytes: stream id, fmt=0
  982 +* where:
  983 +* fmt=0, 0x0X
  984 +* fmt=1, 0x4X
  985 +* fmt=2, 0x8X
  986 +* fmt=3, 0xCX
  987 +*/
929 int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_size, int& mh_size) 988 int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_size, int& mh_size)
930 { 989 {
931 int ret = ERROR_SUCCESS; 990 int ret = ERROR_SUCCESS;
@@ -401,6 +401,9 @@ VOID TEST(ProtocolHandshakeTest, ComplexHandshake) @@ -401,6 +401,9 @@ VOID TEST(ProtocolHandshakeTest, ComplexHandshake)
401 } 401 }
402 } 402 }
403 403
  404 +/**
  405 +* bytes equal utility
  406 +*/
404 VOID TEST(ProtocolHandshakeTest, BytesEqual) 407 VOID TEST(ProtocolHandshakeTest, BytesEqual)
405 { 408 {
406 char a1[] = { (char)0x01 }; 409 char a1[] = { (char)0x01 };
@@ -417,6 +420,9 @@ VOID TEST(ProtocolHandshakeTest, BytesEqual) @@ -417,6 +420,9 @@ VOID TEST(ProtocolHandshakeTest, BytesEqual)
417 EXPECT_FALSE(srs_bytes_equals(a1, b2, 1)); 420 EXPECT_FALSE(srs_bytes_equals(a1, b2, 1));
418 } 421 }
419 422
  423 +/**
  424 +* resolve vhost from tcUrl.
  425 +*/
420 VOID TEST(ProtocolUtilityTest, VhostResolve) 426 VOID TEST(ProtocolUtilityTest, VhostResolve)
421 { 427 {
422 std::string vhost = "vhost"; 428 std::string vhost = "vhost";
@@ -446,6 +452,9 @@ VOID TEST(ProtocolUtilityTest, VhostResolve) @@ -446,6 +452,9 @@ VOID TEST(ProtocolUtilityTest, VhostResolve)
446 EXPECT_STREQ("app", app.c_str()); 452 EXPECT_STREQ("app", app.c_str());
447 } 453 }
448 454
  455 +/**
  456 +* discovery tcUrl to schema/vhost/host/port/app
  457 +*/
449 VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) 458 VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
450 { 459 {
451 std::string tcUrl; 460 std::string tcUrl;
@@ -485,6 +494,9 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) @@ -485,6 +494,9 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
485 EXPECT_STREQ("19351", port.c_str()); 494 EXPECT_STREQ("19351", port.c_str());
486 } 495 }
487 496
  497 +/**
  498 +* generate tcUrl from ip/vhost/app/port
  499 +*/
488 VOID TEST(ProtocolUtilityTest, GenerateTcUrl) 500 VOID TEST(ProtocolUtilityTest, GenerateTcUrl)
489 { 501 {
490 string ip; string vhost; string app; string port; string tcUrl; 502 string ip; string vhost; string app; string port; string tcUrl;
@@ -502,6 +514,9 @@ VOID TEST(ProtocolUtilityTest, GenerateTcUrl) @@ -502,6 +514,9 @@ VOID TEST(ProtocolUtilityTest, GenerateTcUrl)
502 EXPECT_STREQ("rtmp://demo:19351/live", tcUrl.c_str()); 514 EXPECT_STREQ("rtmp://demo:19351/live", tcUrl.c_str());
503 } 515 }
504 516
  517 +/**
  518 +* shared ptr message array test
  519 +*/
505 VOID TEST(ProtocolMsgArrayTest, MessageArray) 520 VOID TEST(ProtocolMsgArrayTest, MessageArray)
506 { 521 {
507 SrsMessageHeader header; 522 SrsMessageHeader header;
@@ -536,6 +551,9 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray) @@ -536,6 +551,9 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray)
536 EXPECT_EQ(0, msg.count()); 551 EXPECT_EQ(0, msg.count());
537 } 552 }
538 553
  554 +/**
  555 +* set/get timeout of protocol stack
  556 +*/
539 VOID TEST(ProtocolStackTest, ProtocolTimeout) 557 VOID TEST(ProtocolStackTest, ProtocolTimeout)
540 { 558 {
541 MockBufferIO bio; 559 MockBufferIO bio;
@@ -551,6 +569,9 @@ VOID TEST(ProtocolStackTest, ProtocolTimeout) @@ -551,6 +569,9 @@ VOID TEST(ProtocolStackTest, ProtocolTimeout)
551 EXPECT_TRUE(10 == proto.get_send_timeout()); 569 EXPECT_TRUE(10 == proto.get_send_timeout());
552 } 570 }
553 571
  572 +/**
  573 +* get recv/send bytes of protocol stack.
  574 +*/
554 VOID TEST(ProtocolStackTest, ProtocolBytes) 575 VOID TEST(ProtocolStackTest, ProtocolBytes)
555 { 576 {
556 MockBufferIO bio; 577 MockBufferIO bio;
@@ -564,6 +585,9 @@ VOID TEST(ProtocolStackTest, ProtocolBytes) @@ -564,6 +585,9 @@ VOID TEST(ProtocolStackTest, ProtocolBytes)
564 EXPECT_TRUE(0 < proto.get_send_bytes()); 585 EXPECT_TRUE(0 < proto.get_send_bytes());
565 } 586 }
566 587
  588 +/**
  589 +* recv a SrsConnectAppPacket packet.
  590 +*/
567 VOID TEST(ProtocolStackTest, ProtocolRecvMessage) 591 VOID TEST(ProtocolStackTest, ProtocolRecvMessage)
568 { 592 {
569 MockBufferIO bio; 593 MockBufferIO bio;
@@ -657,6 +681,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvMessageBug98) @@ -657,6 +681,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvMessageBug98)
657 EXPECT_EQ(0x0d0f, spkt->event_data); 681 EXPECT_EQ(0x0d0f, spkt->event_data);
658 } 682 }
659 683
  684 +/**
  685 +* recv a SrsSetWindowAckSizePacket packet.
  686 +*/
660 VOID TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage) 687 VOID TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage)
661 { 688 {
662 MockBufferIO bio; 689 MockBufferIO bio;
@@ -688,6 +715,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage) @@ -688,6 +715,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvAckSizeMessage)
688 EXPECT_EQ(0x0763, spkt->ackowledgement_window_size); 715 EXPECT_EQ(0x0763, spkt->ackowledgement_window_size);
689 } 716 }
690 717
  718 +/**
  719 +* recv a video message.
  720 +*/
691 VOID TEST(ProtocolStackTest, ProtocolRecvVMessage) 721 VOID TEST(ProtocolStackTest, ProtocolRecvVMessage)
692 { 722 {
693 MockBufferIO bio; 723 MockBufferIO bio;
@@ -712,6 +742,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVMessage) @@ -712,6 +742,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVMessage)
712 EXPECT_TRUE(msg->header.is_video()); 742 EXPECT_TRUE(msg->header.is_video());
713 } 743 }
714 744
  745 +/**
  746 +* recv a audio message.
  747 +*/
715 VOID TEST(ProtocolStackTest, ProtocolRecvAMessage) 748 VOID TEST(ProtocolStackTest, ProtocolRecvAMessage)
716 { 749 {
717 MockBufferIO bio; 750 MockBufferIO bio;
@@ -736,6 +769,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvAMessage) @@ -736,6 +769,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvAMessage)
736 EXPECT_TRUE(msg->header.is_audio()); 769 EXPECT_TRUE(msg->header.is_audio());
737 } 770 }
738 771
  772 +/**
  773 +* recv a video message in 2 chunk packets.
  774 +*/
739 VOID TEST(ProtocolStackTest, ProtocolRecvVMessage2Trunk) 775 VOID TEST(ProtocolStackTest, ProtocolRecvVMessage2Trunk)
740 { 776 {
741 MockBufferIO bio; 777 MockBufferIO bio;
@@ -779,6 +815,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVMessage2Trunk) @@ -779,6 +815,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVMessage2Trunk)
779 EXPECT_TRUE(msg->header.is_video()); 815 EXPECT_TRUE(msg->header.is_video());
780 } 816 }
781 817
  818 +/**
  819 +* recv video and audio, interlaced in chunks.
  820 +*/
782 VOID TEST(ProtocolStackTest, ProtocolRecvVAMessage) 821 VOID TEST(ProtocolStackTest, ProtocolRecvVAMessage)
783 { 822 {
784 MockBufferIO bio; 823 MockBufferIO bio;
@@ -874,6 +913,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAMessage) @@ -874,6 +913,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAMessage)
874 } 913 }
875 } 914 }
876 915
  916 +/**
  917 +* recv video and audio, interlaced in chunks.
  918 +* the continue chunks use fmt=1 header
  919 +*/
877 VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt1) 920 VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt1)
878 { 921 {
879 MockBufferIO bio; 922 MockBufferIO bio;
@@ -988,6 +1031,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt1) @@ -988,6 +1031,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt1)
988 } 1031 }
989 } 1032 }
990 1033
  1034 +/**
  1035 +* recv video and audio, interlaced in chunks.
  1036 +* the continue chunks use fmt=2 header
  1037 +*/
991 VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt2) 1038 VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt2)
992 { 1039 {
993 MockBufferIO bio; 1040 MockBufferIO bio;
@@ -1100,6 +1147,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt2) @@ -1100,6 +1147,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt2)
1100 } 1147 }
1101 } 1148 }
1102 1149
  1150 +/**
  1151 +* recv video and audio, interlaced in chunks.
  1152 +* the continue chunks use fmt=3 header
  1153 +*/
1103 VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt3) 1154 VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt3)
1104 { 1155 {
1105 MockBufferIO bio; 1156 MockBufferIO bio;
@@ -1211,6 +1262,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt3) @@ -1211,6 +1262,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAFmt3)
1211 } 1262 }
1212 } 1263 }
1213 1264
  1265 +/**
  1266 +* recv video, audio and video, interlaced in chunks.
  1267 +*/
1214 VOID TEST(ProtocolStackTest, ProtocolRecvVAVMessage) 1268 VOID TEST(ProtocolStackTest, ProtocolRecvVAVMessage)
1215 { 1269 {
1216 MockBufferIO bio; 1270 MockBufferIO bio;
@@ -1363,6 +1417,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVMessage) @@ -1363,6 +1417,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVMessage)
1363 } 1417 }
1364 } 1418 }
1365 1419
  1420 +/**
  1421 +* recv video, audio and video, interlaced in chunks.
  1422 +* the continue chunks use fmt=1 header
  1423 +*/
1366 VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt1) 1424 VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt1)
1367 { 1425 {
1368 MockBufferIO bio; 1426 MockBufferIO bio;
@@ -1527,6 +1585,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt1) @@ -1527,6 +1585,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt1)
1527 } 1585 }
1528 } 1586 }
1529 1587
  1588 +/**
  1589 +* recv video, audio and video, interlaced in chunks.
  1590 +* the continue chunks use fmt=2 header
  1591 +*/
1530 VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt2) 1592 VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt2)
1531 { 1593 {
1532 MockBufferIO bio; 1594 MockBufferIO bio;
@@ -1689,6 +1751,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt2) @@ -1689,6 +1751,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt2)
1689 } 1751 }
1690 } 1752 }
1691 1753
  1754 +/**
  1755 +* recv video, audio and video, interlaced in chunks.
  1756 +* the continue chunks use fmt=3 header
  1757 +*/
1692 VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt3) 1758 VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt3)
1693 { 1759 {
1694 MockBufferIO bio; 1760 MockBufferIO bio;
@@ -1850,6 +1916,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt3) @@ -1850,6 +1916,9 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVFmt3)
1850 } 1916 }
1851 } 1917 }
1852 1918
  1919 +/**
  1920 +* recv video, audio, video and video, interlaced in chunks.
  1921 +*/
1853 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVMessage) 1922 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVMessage)
1854 { 1923 {
1855 MockBufferIO bio; 1924 MockBufferIO bio;
@@ -2055,6 +2124,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVMessage) @@ -2055,6 +2124,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVMessage)
2055 } 2124 }
2056 } 2125 }
2057 2126
  2127 +/**
  2128 +* recv video, audio, video and video, interlaced in chunks.
  2129 +* the continue chunks use fmt=1 header
  2130 +*/
2058 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1) 2131 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1)
2059 { 2132 {
2060 MockBufferIO bio; 2133 MockBufferIO bio;
@@ -2271,6 +2344,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1) @@ -2271,6 +2344,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt1)
2271 } 2344 }
2272 } 2345 }
2273 2346
  2347 +/**
  2348 +* recv video, audio, video and video, interlaced in chunks.
  2349 +* the continue chunks use fmt=2 header
  2350 +*/
2274 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2) 2351 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2)
2275 { 2352 {
2276 MockBufferIO bio; 2353 MockBufferIO bio;
@@ -2483,6 +2560,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2) @@ -2483,6 +2560,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt2)
2483 } 2560 }
2484 } 2561 }
2485 2562
  2563 +/**
  2564 +* recv video, audio, video and video, interlaced in chunks.
  2565 +* the continue chunks use fmt=3 header
  2566 +*/
2486 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3) 2567 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3)
2487 { 2568 {
2488 MockBufferIO bio; 2569 MockBufferIO bio;
@@ -2693,6 +2774,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3) @@ -2693,6 +2774,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt3)
2693 } 2774 }
2694 } 2775 }
2695 2776
  2777 +/**
  2778 +* recv video, audio, video and video, interlaced in chunks.
  2779 +* the continue chunks use fmt=1, last video with fmt=1 header
  2780 +*/
2696 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11) 2781 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11)
2697 { 2782 {
2698 MockBufferIO bio; 2783 MockBufferIO bio;
@@ -2909,6 +2994,11 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11) @@ -2909,6 +2994,11 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11)
2909 } 2994 }
2910 } 2995 }
2911 2996
  2997 +/**
  2998 +* recv video, audio, video and video, interlaced in chunks.
  2999 +* the continue chunks use fmt=1, last video with fmt=1 header,
  3000 +* last video changed length
  3001 +*/
2912 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length) 3002 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length)
2913 { 3003 {
2914 MockBufferIO bio; 3004 MockBufferIO bio;
@@ -3126,6 +3216,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length) @@ -3126,6 +3216,10 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt11Length)
3126 } 3216 }
3127 } 3217 }
3128 3218
  3219 +/**
  3220 +* recv video, audio, video and video, interlaced in chunks.
  3221 +* the continue chunks use fmt=1, last video with fmt=2 header
  3222 +*/
3129 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12) 3223 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12)
3130 { 3224 {
3131 MockBufferIO bio; 3225 MockBufferIO bio;
@@ -3340,6 +3434,11 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12) @@ -3340,6 +3434,11 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12)
3340 } 3434 }
3341 } 3435 }
3342 3436
  3437 +/**
  3438 +* recv video, audio, video and video, interlaced in chunks.
  3439 +* the continue chunks use fmt=1, last video with fmt=2 header,
  3440 +* last video changed length
  3441 +*/
3343 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length) 3442 VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length)
3344 { 3443 {
3345 MockBufferIO bio; 3444 MockBufferIO bio;
@@ -3559,3 +3658,770 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length) @@ -3559,3 +3658,770 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVAVVFmt12Length)
3559 } 3658 }
3560 } 3659 }
3561 3660
  3661 +/**
  3662 +* recv video, with extended timestamp.
  3663 +* small timestamp < 0xffffff
  3664 +*/
  3665 +VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage)
  3666 +{
  3667 + MockBufferIO bio;
  3668 + SrsProtocol proto(&bio);
  3669 +
  3670 + /**
  3671 + * parse the message header.
  3672 + * 3bytes: timestamp delta, fmt=0,1,2
  3673 + * 3bytes: payload length, fmt=0,1
  3674 + * 1bytes: message type, fmt=0,1
  3675 + * 4bytes: stream id, fmt=0
  3676 + * where:
  3677 + * fmt=0, 0x0X
  3678 + * fmt=1, 0x4X
  3679 + * fmt=2, 0x8X
  3680 + * fmt=3, 0xCX
  3681 + */
  3682 +
  3683 + char data[] = {
  3684 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3685 + (char)0x03,
  3686 + (char)0xff, (char)0xff, (char)0xff, // timestamp
  3687 + (char)0x00, (char)0x00, (char)0x04, // length
  3688 + (char)0x09, // message_type
  3689 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3690 + (char)0x00, (char)0x00, (char)0x00, (char)0x10, // extended timestamp
  3691 + // msg payload start
  3692 + (char)0x00, (char)0x00, (char)0x07, (char)0x63
  3693 + };
  3694 + bio.in_buffer.append(data, sizeof(data));
  3695 +
  3696 + SrsMessage* msg = NULL;
  3697 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  3698 + SrsAutoFree(SrsMessage, msg);
  3699 + EXPECT_TRUE(msg->header.is_video());
  3700 + EXPECT_EQ(0x10, msg->header.timestamp);
  3701 +}
  3702 +
  3703 +/**
  3704 +* recv video, with extended timestamp.
  3705 +* big timestamp > 0xffffff
  3706 +*/
  3707 +VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage2)
  3708 +{
  3709 + MockBufferIO bio;
  3710 + SrsProtocol proto(&bio);
  3711 +
  3712 + /**
  3713 + * parse the message header.
  3714 + * 3bytes: timestamp delta, fmt=0,1,2
  3715 + * 3bytes: payload length, fmt=0,1
  3716 + * 1bytes: message type, fmt=0,1
  3717 + * 4bytes: stream id, fmt=0
  3718 + * where:
  3719 + * fmt=0, 0x0X
  3720 + * fmt=1, 0x4X
  3721 + * fmt=2, 0x8X
  3722 + * fmt=3, 0xCX
  3723 + */
  3724 +
  3725 + char data[] = {
  3726 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3727 + (char)0x03,
  3728 + (char)0xff, (char)0xff, (char)0xff, // timestamp
  3729 + (char)0x00, (char)0x00, (char)0x04, // length
  3730 + (char)0x09, // message_type
  3731 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3732 + (char)0x7f, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
  3733 + // msg payload start
  3734 + (char)0x00, (char)0x00, (char)0x07, (char)0x63
  3735 + };
  3736 + bio.in_buffer.append(data, sizeof(data));
  3737 +
  3738 + SrsMessage* msg = NULL;
  3739 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  3740 + SrsAutoFree(SrsMessage, msg);
  3741 + EXPECT_TRUE(msg->header.is_video());
  3742 + EXPECT_EQ(0x7f010203, msg->header.timestamp);
  3743 +}
  3744 +
  3745 +/**
  3746 +* recv video, with extended timestamp.
  3747 +* always use 31bits timestamp.
  3748 +*/
  3749 +// always use 31bits timestamp, for some server may use 32bits extended timestamp.
  3750 +// @see https://github.com/winlinvip/simple-rtmp-server/issues/111
  3751 +VOID TEST(ProtocolStackTest, ProtocolRecvExtTimeMessage3)
  3752 +{
  3753 + MockBufferIO bio;
  3754 + SrsProtocol proto(&bio);
  3755 +
  3756 + /**
  3757 + * parse the message header.
  3758 + * 3bytes: timestamp delta, fmt=0,1,2
  3759 + * 3bytes: payload length, fmt=0,1
  3760 + * 1bytes: message type, fmt=0,1
  3761 + * 4bytes: stream id, fmt=0
  3762 + * where:
  3763 + * fmt=0, 0x0X
  3764 + * fmt=1, 0x4X
  3765 + * fmt=2, 0x8X
  3766 + * fmt=3, 0xCX
  3767 + */
  3768 +
  3769 + char data[] = {
  3770 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3771 + (char)0x03,
  3772 + (char)0xff, (char)0xff, (char)0xff, // timestamp
  3773 + (char)0x00, (char)0x00, (char)0x04, // length
  3774 + (char)0x09, // message_type
  3775 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3776 + (char)0xff, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
  3777 + // msg payload start
  3778 + (char)0x00, (char)0x00, (char)0x07, (char)0x63
  3779 + };
  3780 + bio.in_buffer.append(data, sizeof(data));
  3781 +
  3782 + SrsMessage* msg = NULL;
  3783 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  3784 + SrsAutoFree(SrsMessage, msg);
  3785 + EXPECT_TRUE(msg->header.is_video());
  3786 + // always use 31bits timestamp
  3787 + EXPECT_EQ(0x7f010203, msg->header.timestamp);
  3788 +}
  3789 +
  3790 +/**
  3791 +* recv video, with extended timestamp, in 2 chunks packet.
  3792 +* always send extended timestamp in 0xCX chunk packets.
  3793 +*/
  3794 +/**
  3795 +* RTMP specification and ffmpeg/librtmp is false,
  3796 +* but, adobe changed the specification, so flash/FMLE/FMS always true.
  3797 +* default to true to support flash/FMLE/FMS.
  3798 +*
  3799 +* ffmpeg/librtmp may donot send this filed, need to detect the value.
  3800 +* @see also: http://blog.csdn.net/win_lin/article/details/13363699
  3801 +* compare to the chunk timestamp, which is set by chunk message header
  3802 +* type 0,1 or 2.
  3803 +*
  3804 +* @remark, nginx send the extended-timestamp in sequence-header,
  3805 +* and timestamp delta in continue C1 chunks, and so compatible with ffmpeg,
  3806 +* that is, there is no continue chunks and extended-timestamp in nginx-rtmp.
  3807 +*
  3808 +* @remark, srs always send the extended-timestamp, to keep simple,
  3809 +* and compatible with adobe products.
  3810 +*/
  3811 +VOID TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk)
  3812 +{
  3813 + MockBufferIO bio;
  3814 + SrsProtocol proto(&bio);
  3815 +
  3816 + // video message
  3817 + char data[] = {
  3818 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3819 + (char)0x03,
  3820 + (char)0xff, (char)0xff, (char)0xff, // timestamp
  3821 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  3822 + (char)0x09, // message_type
  3823 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3824 + (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
  3825 + // msg payload start
  3826 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  3827 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  3828 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  3829 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  3830 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  3831 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  3832 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  3833 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  3834 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  3835 + // chunk #2
  3836 + (char)0xC3,
  3837 + (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
  3838 + /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  3839 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  3840 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  3841 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  3842 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  3843 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  3844 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  3845 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  3846 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  3847 + // chunk #2
  3848 + (char)0xC3,
  3849 + (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
  3850 + /*next chunk.*/
  3851 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  3852 + };
  3853 + bio.in_buffer.append(data, sizeof(data));
  3854 +
  3855 + SrsMessage* msg = NULL;
  3856 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  3857 + SrsAutoFree(SrsMessage, msg);
  3858 + EXPECT_TRUE(msg->header.is_video());
  3859 + // 0xCX with extended timestamp.
  3860 + EXPECT_EQ(0x00010203, msg->header.timestamp);
  3861 +}
  3862 +
  3863 +/**
  3864 +* recv video, with extended timestamp, in 2 chunks packet.
  3865 +* never send extended timestamp in 0xCX chunk packets.
  3866 +*/
  3867 +// FFMPEG/librtmp, RTMP specification standard protocol.
  3868 +VOID TEST(ProtocolStackTest, ProtocolRecvVExtTime2Trunk2)
  3869 +{
  3870 + MockBufferIO bio;
  3871 + SrsProtocol proto(&bio);
  3872 +
  3873 + // video message
  3874 + char data[] = {
  3875 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3876 + (char)0x03,
  3877 + (char)0xff, (char)0xff, (char)0xff, // timestamp
  3878 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  3879 + (char)0x09, // message_type
  3880 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3881 + (char)0x00, (char)0x01, (char)0x02, (char)0x03, // extended timestamp
  3882 + // msg payload start
  3883 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  3884 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  3885 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  3886 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  3887 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  3888 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  3889 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  3890 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  3891 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  3892 + // chunk #2
  3893 + (char)0xC3,
  3894 + /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  3895 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  3896 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  3897 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  3898 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  3899 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  3900 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  3901 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  3902 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  3903 + // chunk #2
  3904 + (char)0xC3,
  3905 + /*next chunk.*/
  3906 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  3907 + };
  3908 + bio.in_buffer.append(data, sizeof(data));
  3909 +
  3910 + SrsMessage* msg = NULL;
  3911 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  3912 + SrsAutoFree(SrsMessage, msg);
  3913 + EXPECT_TRUE(msg->header.is_video());
  3914 + // 0xCX without extended timestamp.
  3915 + EXPECT_EQ(0x00010203, msg->header.timestamp);
  3916 +}
  3917 +
  3918 +/**
  3919 +* a video message, in 2 chunks packet.
  3920 +* use 1B chunk header, min chunk id is 2.
  3921 +*/
  3922 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMin)
  3923 +{
  3924 + MockBufferIO bio;
  3925 + SrsProtocol proto(&bio);
  3926 +
  3927 + // video message
  3928 + char data[] = {
  3929 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3930 + (char)0x02,
  3931 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  3932 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  3933 + (char)0x09, // message_type
  3934 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3935 + // msg payload start
  3936 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  3937 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  3938 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  3939 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  3940 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  3941 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  3942 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  3943 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  3944 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  3945 + // chunk #2
  3946 + (char)0xC2, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  3947 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  3948 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  3949 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  3950 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  3951 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  3952 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  3953 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  3954 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  3955 + // chunk #2
  3956 + (char)0xC2, /*next chunk.*/
  3957 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  3958 + };
  3959 + bio.in_buffer.append(data, sizeof(data));
  3960 +
  3961 + SrsMessage* msg = NULL;
  3962 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  3963 + SrsAutoFree(SrsMessage, msg);
  3964 + EXPECT_TRUE(msg->header.is_video());
  3965 + // 1B cid(6bits), min is 2
  3966 + EXPECT_EQ(0x02, msg->header.perfer_cid);
  3967 +}
  3968 +
  3969 +/**
  3970 +* a video message, in 2 chunks packet.
  3971 +* use 1B chunk header, cid in 2-63
  3972 +*/
  3973 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BNormal)
  3974 +{
  3975 + MockBufferIO bio;
  3976 + SrsProtocol proto(&bio);
  3977 +
  3978 + // video message
  3979 + char data[] = {
  3980 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  3981 + (char)0x09,
  3982 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  3983 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  3984 + (char)0x09, // message_type
  3985 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  3986 + // msg payload start
  3987 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  3988 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  3989 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  3990 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  3991 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  3992 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  3993 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  3994 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  3995 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  3996 + // chunk #2
  3997 + (char)0xC9, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  3998 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  3999 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4000 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4001 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4002 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4003 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4004 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4005 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4006 + // chunk #2
  4007 + (char)0xC9, /*next chunk.*/
  4008 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4009 + };
  4010 + bio.in_buffer.append(data, sizeof(data));
  4011 +
  4012 + SrsMessage* msg = NULL;
  4013 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4014 + SrsAutoFree(SrsMessage, msg);
  4015 + EXPECT_TRUE(msg->header.is_video());
  4016 + // 1B cid(6bits), cid in 2-63
  4017 + EXPECT_EQ(0x09, msg->header.perfer_cid);
  4018 +}
  4019 +
  4020 +/**
  4021 +* a video message, in 2 chunks packet.
  4022 +* use 1B chunk header, max chunk id is 63.
  4023 +*/
  4024 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid1BMax)
  4025 +{
  4026 + MockBufferIO bio;
  4027 + SrsProtocol proto(&bio);
  4028 +
  4029 + // video message
  4030 + char data[] = {
  4031 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4032 + (char)0x3F,
  4033 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4034 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4035 + (char)0x09, // message_type
  4036 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4037 + // msg payload start
  4038 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4039 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4040 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4041 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4042 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4043 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4044 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4045 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4046 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4047 + // chunk #2
  4048 + (char)0xFF, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4049 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4050 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4051 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4052 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4053 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4054 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4055 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4056 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4057 + // chunk #2
  4058 + (char)0xFF, /*next chunk.*/
  4059 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4060 + };
  4061 + bio.in_buffer.append(data, sizeof(data));
  4062 +
  4063 + SrsMessage* msg = NULL;
  4064 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4065 + SrsAutoFree(SrsMessage, msg);
  4066 + EXPECT_TRUE(msg->header.is_video());
  4067 + // 1B cid(6bits), max is 63
  4068 + EXPECT_EQ(0x3F, msg->header.perfer_cid);
  4069 +}
  4070 +
  4071 +/**
  4072 +* a video message, in 2 chunks packet.
  4073 +* use 2B chunk header, min chunk id is 64.
  4074 +*/
  4075 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BMin)
  4076 +{
  4077 + MockBufferIO bio;
  4078 + SrsProtocol proto(&bio);
  4079 +
  4080 + // video message
  4081 + char data[] = {
  4082 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4083 + (char)0x00, (char)0x00,
  4084 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4085 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4086 + (char)0x09, // message_type
  4087 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4088 + // msg payload start
  4089 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4090 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4091 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4092 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4093 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4094 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4095 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4096 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4097 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4098 + // chunk #2
  4099 + (char)0xC0, (char)0x00, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4100 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4101 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4102 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4103 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4104 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4105 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4106 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4107 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4108 + // chunk #2
  4109 + (char)0xC0, (char)0x00, /*next chunk.*/
  4110 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4111 + };
  4112 + bio.in_buffer.append(data, sizeof(data));
  4113 +
  4114 + SrsMessage* msg = NULL;
  4115 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4116 + SrsAutoFree(SrsMessage, msg);
  4117 + EXPECT_TRUE(msg->header.is_video());
  4118 + // 2B cid(8bits), min is 64
  4119 + EXPECT_EQ(64, msg->header.perfer_cid);
  4120 +}
  4121 +
  4122 +/**
  4123 +* a video message, in 2 chunks packet.
  4124 +* use 2B chunk header, cid in 64-319
  4125 +*/
  4126 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BNormal)
  4127 +{
  4128 + MockBufferIO bio;
  4129 + SrsProtocol proto(&bio);
  4130 +
  4131 + // video message
  4132 + char data[] = {
  4133 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4134 + (char)0x00, (char)0x10,
  4135 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4136 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4137 + (char)0x09, // message_type
  4138 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4139 + // msg payload start
  4140 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4141 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4142 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4143 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4144 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4145 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4146 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4147 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4148 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4149 + // chunk #2
  4150 + (char)0xC0, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4151 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4152 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4153 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4154 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4155 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4156 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4157 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4158 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4159 + // chunk #2
  4160 + (char)0xC0, (char)0x10, /*next chunk.*/
  4161 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4162 + };
  4163 + bio.in_buffer.append(data, sizeof(data));
  4164 +
  4165 + SrsMessage* msg = NULL;
  4166 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4167 + SrsAutoFree(SrsMessage, msg);
  4168 + EXPECT_TRUE(msg->header.is_video());
  4169 + // 2B cid(8bits), cid in 64-319
  4170 + EXPECT_EQ(0x10+64, msg->header.perfer_cid);
  4171 +}
  4172 +
  4173 +/**
  4174 +* a video message, in 2 chunks packet.
  4175 +* use 2B chunk header, max chunk id is 319.
  4176 +*/
  4177 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid2BMax)
  4178 +{
  4179 + MockBufferIO bio;
  4180 + SrsProtocol proto(&bio);
  4181 +
  4182 + // video message
  4183 + char data[] = {
  4184 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4185 + (char)0x00, (char)0xFF,
  4186 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4187 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4188 + (char)0x09, // message_type
  4189 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4190 + // msg payload start
  4191 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4192 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4193 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4194 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4195 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4196 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4197 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4198 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4199 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4200 + // chunk #2
  4201 + (char)0xC0, (char)0xFF, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4202 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4203 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4204 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4205 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4206 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4207 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4208 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4209 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4210 + // chunk #2
  4211 + (char)0xC0, (char)0xFF, /*next chunk.*/
  4212 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4213 + };
  4214 + bio.in_buffer.append(data, sizeof(data));
  4215 +
  4216 + SrsMessage* msg = NULL;
  4217 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4218 + SrsAutoFree(SrsMessage, msg);
  4219 + EXPECT_TRUE(msg->header.is_video());
  4220 + // 2B cid(68bits), max is 319
  4221 + EXPECT_EQ(319, msg->header.perfer_cid);
  4222 +}
  4223 +
  4224 +/**
  4225 +* a video message, in 2 chunks packet.
  4226 +* use 3B chunk header, min chunk id is 64.
  4227 +*/
  4228 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMin)
  4229 +{
  4230 + MockBufferIO bio;
  4231 + SrsProtocol proto(&bio);
  4232 +
  4233 + // video message
  4234 + char data[] = {
  4235 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4236 + (char)0x01, (char)0x00, (char)0x00,
  4237 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4238 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4239 + (char)0x09, // message_type
  4240 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4241 + // msg payload start
  4242 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4243 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4244 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4245 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4246 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4247 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4248 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4249 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4250 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4251 + // chunk #2
  4252 + (char)0xC1, (char)0x00, (char)0x00, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4253 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4254 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4255 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4256 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4257 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4258 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4259 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4260 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4261 + // chunk #2
  4262 + (char)0xC1, (char)0x00, (char)0x00, /*next chunk.*/
  4263 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4264 + };
  4265 + bio.in_buffer.append(data, sizeof(data));
  4266 +
  4267 + SrsMessage* msg = NULL;
  4268 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4269 + SrsAutoFree(SrsMessage, msg);
  4270 + EXPECT_TRUE(msg->header.is_video());
  4271 + // 3B cid(16bits), min is 64
  4272 + EXPECT_EQ(64, msg->header.perfer_cid);
  4273 +}
  4274 +
  4275 +/**
  4276 +* a video message, in 2 chunks packet.
  4277 +* use 3B chunk header, cid in 64-65599
  4278 +*/
  4279 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal)
  4280 +{
  4281 + MockBufferIO bio;
  4282 + SrsProtocol proto(&bio);
  4283 +
  4284 + // video message
  4285 + char data[] = {
  4286 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4287 + (char)0x01, (char)0x00, (char)0x10,
  4288 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4289 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4290 + (char)0x09, // message_type
  4291 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4292 + // msg payload start
  4293 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4294 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4295 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4296 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4297 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4298 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4299 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4300 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4301 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4302 + // chunk #2
  4303 + (char)0xC1, (char)0x00, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4304 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4305 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4306 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4307 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4308 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4309 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4310 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4311 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4312 + // chunk #2
  4313 + (char)0xC1, (char)0x00, (char)0x10, /*next chunk.*/
  4314 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4315 + };
  4316 + bio.in_buffer.append(data, sizeof(data));
  4317 +
  4318 + SrsMessage* msg = NULL;
  4319 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4320 + SrsAutoFree(SrsMessage, msg);
  4321 + EXPECT_TRUE(msg->header.is_video());
  4322 + // 3B cid(16bits), cid in 64-65599
  4323 + EXPECT_EQ(0x10*256+64, msg->header.perfer_cid);
  4324 +}
  4325 +
  4326 +/**
  4327 +* a video message, in 2 chunks packet.
  4328 +* use 3B chunk header, cid in 64-65599, greater than 319
  4329 +*/
  4330 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BNormal2)
  4331 +{
  4332 + MockBufferIO bio;
  4333 + SrsProtocol proto(&bio);
  4334 +
  4335 + // video message
  4336 + char data[] = {
  4337 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4338 + (char)0x01, (char)0x01, (char)0x10,
  4339 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4340 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4341 + (char)0x09, // message_type
  4342 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4343 + // msg payload start
  4344 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4345 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4346 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4347 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4348 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4349 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4350 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4351 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4352 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4353 + // chunk #2
  4354 + (char)0xC1, (char)0x01, (char)0x10, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4355 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4356 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4357 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4358 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4359 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4360 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4361 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4362 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4363 + // chunk #2
  4364 + (char)0xC1, (char)0x01, (char)0x10, /*next chunk.*/
  4365 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4366 + };
  4367 + bio.in_buffer.append(data, sizeof(data));
  4368 +
  4369 + SrsMessage* msg = NULL;
  4370 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4371 + SrsAutoFree(SrsMessage, msg);
  4372 + EXPECT_TRUE(msg->header.is_video());
  4373 + // 3B cid(16bits), cid in 64-65599
  4374 + EXPECT_EQ(0x01 + (0x10*256) + 64, msg->header.perfer_cid);
  4375 +}
  4376 +
  4377 +/**
  4378 +* a video message, in 2 chunks packet.
  4379 +* use 3B chunk header, max chunk id is 65599.
  4380 +*/
  4381 +VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMax)
  4382 +{
  4383 + MockBufferIO bio;
  4384 + SrsProtocol proto(&bio);
  4385 +
  4386 + // video message
  4387 + char data[] = {
  4388 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  4389 + (char)0x01, (char)0xFF, (char)0xFF,
  4390 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  4391 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  4392 + (char)0x09, // message_type
  4393 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  4394 + // msg payload start
  4395 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  4396 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  4397 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  4398 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  4399 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  4400 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  4401 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  4402 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  4403 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  4404 + // chunk #2
  4405 + (char)0xC1, (char)0xFF, (char)0xFF, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  4406 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  4407 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  4408 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  4409 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  4410 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4411 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  4412 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  4413 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  4414 + // chunk #2
  4415 + (char)0xC1, (char)0xFF, (char)0xFF, /*next chunk.*/
  4416 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  4417 + };
  4418 + bio.in_buffer.append(data, sizeof(data));
  4419 +
  4420 + SrsMessage* msg = NULL;
  4421 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  4422 + SrsAutoFree(SrsMessage, msg);
  4423 + EXPECT_TRUE(msg->header.is_video());
  4424 + // 2B cid(16bits), max is 65599
  4425 + EXPECT_EQ(65599, msg->header.perfer_cid);
  4426 +}
  4427 +