winlin

fix the rtmp dump, parse the aggregate msg.

@@ -272,11 +272,19 @@ int main(int argc, char** argv) @@ -272,11 +272,19 @@ int main(int argc, char** argv)
272 goto rtmp_destroy; 272 goto rtmp_destroy;
273 } 273 }
274 274
  275 + // we only write some types of messages to flv file.
  276 + int is_flv_msg = type == SRS_RTMP_TYPE_AUDIO
  277 + || type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT;
  278 +
275 if (flv) { 279 if (flv) {
  280 + if (is_flv_msg) {
276 if (srs_flv_write_tag(flv, type, timestamp, data, size) != 0) { 281 if (srs_flv_write_tag(flv, type, timestamp, data, size) != 0) {
277 srs_human_trace("dump rtmp packet failed."); 282 srs_human_trace("dump rtmp packet failed.");
278 goto rtmp_destroy; 283 goto rtmp_destroy;
279 } 284 }
  285 + } else {
  286 + srs_human_trace("drop message size=%dB", size);
  287 + }
280 } 288 }
281 289
282 free(data); 290 free(data);
@@ -70,6 +70,12 @@ struct Context @@ -70,6 +70,12 @@ struct Context
70 // extra request object for connect to server, NULL to ignore. 70 // extra request object for connect to server, NULL to ignore.
71 SrsRequest* req; 71 SrsRequest* req;
72 72
  73 + // the message received cache,
  74 + // for example, when got aggregate message,
  75 + // the context will parse to videos/audios,
  76 + // and return one by one.
  77 + std::vector<SrsCommonMessage*> msgs;
  78 +
73 SrsRtmpClient* rtmp; 79 SrsRtmpClient* rtmp;
74 SimpleSocketStream* skt; 80 SimpleSocketStream* skt;
75 int stream_id; 81 int stream_id;
@@ -106,6 +112,13 @@ struct Context @@ -106,6 +112,13 @@ struct Context
106 srs_freep(req); 112 srs_freep(req);
107 srs_freep(rtmp); 113 srs_freep(rtmp);
108 srs_freep(skt); 114 srs_freep(skt);
  115 +
  116 + std::vector<SrsCommonMessage*>::iterator it;
  117 + for (it = msgs.begin(); it != msgs.end(); ++it) {
  118 + SrsCommonMessage* msg = *it;
  119 + srs_freep(msg);
  120 + }
  121 + msgs.clear();
109 } 122 }
110 }; 123 };
111 124
@@ -799,28 +812,119 @@ int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp, @@ -799,28 +812,119 @@ int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp,
799 return ret; 812 return ret;
800 } 813 }
801 814
802 -int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char** data, int* size)  
803 -{  
804 - *type = 0;  
805 - *timestamp = 0;  
806 - *data = NULL;  
807 - *size = 0;  
808 815
  816 +int __srs_rtmp_on_aggregate(Context* context, SrsCommonMessage* msg)
  817 +{
809 int ret = ERROR_SUCCESS; 818 int ret = ERROR_SUCCESS;
810 819
811 - srs_assert(rtmp != NULL);  
812 - Context* context = (Context*)rtmp; 820 + SrsStream aggregate_stream;
  821 + SrsStream* stream = &aggregate_stream;
  822 + if ((ret = stream->initialize(msg->payload, msg->size)) != ERROR_SUCCESS) {
  823 + return ret;
  824 + }
813 825
814 - for (;;) {  
815 - SrsCommonMessage* msg = NULL;  
816 - if ((ret = context->rtmp->recv_message(&msg)) != ERROR_SUCCESS) { 826 + int delta = -1;
  827 + while (!stream->empty()) {
  828 + if (!stream->require(1)) {
  829 + ret = ERROR_RTMP_AGGREGATE;
  830 + srs_error("invalid aggregate message type. ret=%d", ret);
817 return ret; 831 return ret;
818 } 832 }
819 - if (!msg) {  
820 - continue; 833 + int8_t type = stream->read_1bytes();
  834 +
  835 + if (!stream->require(3)) {
  836 + ret = ERROR_RTMP_AGGREGATE;
  837 + srs_error("invalid aggregate message size. ret=%d", ret);
  838 + return ret;
821 } 839 }
  840 + int32_t data_size = stream->read_3bytes();
822 841
823 - SrsAutoFree(SrsCommonMessage, msg); 842 + if (data_size < 0) {
  843 + ret = ERROR_RTMP_AGGREGATE;
  844 + srs_error("invalid aggregate message size(negative). ret=%d", ret);
  845 + return ret;
  846 + }
  847 +
  848 + if (!stream->require(3)) {
  849 + ret = ERROR_RTMP_AGGREGATE;
  850 + srs_error("invalid aggregate message time. ret=%d", ret);
  851 + return ret;
  852 + }
  853 + int32_t timestamp = stream->read_3bytes();
  854 +
  855 + if (!stream->require(1)) {
  856 + ret = ERROR_RTMP_AGGREGATE;
  857 + srs_error("invalid aggregate message time(high). ret=%d", ret);
  858 + return ret;
  859 + }
  860 + int32_t time_h = stream->read_1bytes();
  861 +
  862 + timestamp |= time_h<<24;
  863 + timestamp &= 0x7FFFFFFF;
  864 +
  865 + // adjust timestamp.
  866 + if (delta < 0) {
  867 + delta = (int)msg->header.timestamp - (int)timestamp;
  868 + }
  869 + timestamp += delta;
  870 +
  871 + if (!stream->require(3)) {
  872 + ret = ERROR_RTMP_AGGREGATE;
  873 + srs_error("invalid aggregate message stream_id. ret=%d", ret);
  874 + return ret;
  875 + }
  876 + int32_t stream_id = stream->read_3bytes();
  877 +
  878 + if (data_size > 0 && !stream->require(data_size)) {
  879 + ret = ERROR_RTMP_AGGREGATE;
  880 + srs_error("invalid aggregate message data. ret=%d", ret);
  881 + return ret;
  882 + }
  883 +
  884 + // to common message.
  885 + SrsCommonMessage __o;
  886 + SrsCommonMessage& o = __o;
  887 +
  888 + o.header.message_type = type;
  889 + o.header.payload_length = data_size;
  890 + o.header.timestamp_delta = timestamp;
  891 + o.header.timestamp = timestamp;
  892 + o.header.stream_id = stream_id;
  893 + o.header.perfer_cid = msg->header.perfer_cid;
  894 +
  895 + if (data_size > 0) {
  896 + o.size = data_size;
  897 + o.payload = new char[o.size];
  898 + stream->read_bytes(o.payload, o.size);
  899 + }
  900 +
  901 + if (!stream->require(4)) {
  902 + ret = ERROR_RTMP_AGGREGATE;
  903 + srs_error("invalid aggregate message previous tag size. ret=%d", ret);
  904 + return ret;
  905 + }
  906 + stream->read_4bytes();
  907 +
  908 + // process parsed message
  909 + SrsCommonMessage* parsed_msg = new SrsCommonMessage();
  910 + parsed_msg->header = o.header;
  911 + parsed_msg->payload = o.payload;
  912 + parsed_msg->size = o.size;
  913 + o.payload = NULL;
  914 + context->msgs.push_back(parsed_msg);
  915 + }
  916 +
  917 + return ret;
  918 +}
  919 +
  920 +int __srs_rtmp_go_packet(Context* context, SrsCommonMessage* msg,
  921 + char* type, u_int32_t* timestamp, char** data, int* size,
  922 + bool* got_msg
  923 +) {
  924 + int ret = ERROR_SUCCESS;
  925 +
  926 + // generally we got a message.
  927 + *got_msg = true;
824 928
825 if (msg->header.is_audio()) { 929 if (msg->header.is_audio()) {
826 *type = SRS_RTMP_TYPE_AUDIO; 930 *type = SRS_RTMP_TYPE_AUDIO;
@@ -842,6 +946,11 @@ int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char @@ -842,6 +946,11 @@ int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char
842 *size = (int)msg->size; 946 *size = (int)msg->size;
843 // detach bytes from packet. 947 // detach bytes from packet.
844 msg->payload = NULL; 948 msg->payload = NULL;
  949 + } else if (msg->header.is_aggregate()) {
  950 + if ((ret = __srs_rtmp_on_aggregate(context, msg)) != ERROR_SUCCESS) {
  951 + return ret;
  952 + }
  953 + *got_msg = false;
845 } else { 954 } else {
846 *type = msg->header.message_type; 955 *type = msg->header.message_type;
847 *data = (char*)msg->payload; 956 *data = (char*)msg->payload;
@@ -850,9 +959,54 @@ int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char @@ -850,9 +959,54 @@ int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char
850 msg->payload = NULL; 959 msg->payload = NULL;
851 } 960 }
852 961
  962 + return ret;
  963 +}
  964 +
  965 +int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char** data, int* size)
  966 +{
  967 + *type = 0;
  968 + *timestamp = 0;
  969 + *data = NULL;
  970 + *size = 0;
  971 +
  972 + int ret = ERROR_SUCCESS;
  973 +
  974 + srs_assert(rtmp != NULL);
  975 + Context* context = (Context*)rtmp;
  976 +
  977 + for (;;) {
  978 + SrsCommonMessage* msg = NULL;
  979 +
  980 + // read from cache first.
  981 + if (!context->msgs.empty()) {
  982 + std::vector<SrsCommonMessage*>::iterator it = context->msgs.begin();
  983 + msg = *it;
  984 + context->msgs.erase(it);
  985 + }
  986 +
  987 + // read from protocol sdk.
  988 + if (!msg && (ret = context->rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
  989 + return ret;
  990 + }
  991 +
  992 + // no msg, try again.
  993 + if (!msg) {
  994 + continue;
  995 + }
  996 +
  997 + SrsAutoFree(SrsCommonMessage, msg);
  998 +
  999 + // process the got packet, if nothing, try again.
  1000 + bool got_msg;
  1001 + if ((ret = __srs_rtmp_go_packet(context, msg, type, timestamp, data, size, &got_msg)) != ERROR_SUCCESS) {
  1002 + return ret;
  1003 + }
  1004 +
853 // got expected message. 1005 // got expected message.
  1006 + if (got_msg) {
854 break; 1007 break;
855 } 1008 }
  1009 + }
856 1010
857 return ret; 1011 return ret;
858 } 1012 }