winlin

refine examples of srs-librtmp, add srs_print_rtmp_packet. 2.0.28.

@@ -482,6 +482,7 @@ Supported operating systems and hardware: @@ -482,6 +482,7 @@ Supported operating systems and hardware:
482 * 2013-10-17, Created.<br/> 482 * 2013-10-17, Created.<br/>
483 483
484 ## History 484 ## History
  485 +* v2.0, 2014-11-21, refine examples of srs-librtmp, add srs_print_rtmp_packet. 2.0.28.
485 * v2.0, 2014-11-20, fix [#212](https://github.com/winlinvip/simple-rtmp-server/issues/212), support publish audio raw frames. 2.0.27 486 * v2.0, 2014-11-20, fix [#212](https://github.com/winlinvip/simple-rtmp-server/issues/212), support publish audio raw frames. 2.0.27
486 * v2.0, 2014-11-19, fix [#213](https://github.com/winlinvip/simple-rtmp-server/issues/213), support compile [srs-librtmp on windows](https://github.com/winlinvip/srs.librtmp), [bug #213](https://github.com/winlinvip/simple-rtmp-server/issues/213). 2.0.26 487 * v2.0, 2014-11-19, fix [#213](https://github.com/winlinvip/simple-rtmp-server/issues/213), support compile [srs-librtmp on windows](https://github.com/winlinvip/srs.librtmp), [bug #213](https://github.com/winlinvip/simple-rtmp-server/issues/213). 2.0.26
487 * v2.0, 2014-11-18, all wiki translated to English. 2.0.23. 488 * v2.0, 2014-11-18, all wiki translated to English. 2.0.23.
@@ -124,86 +124,6 @@ int parse_bytes(char* data, int size, char* hbuf, int hsize, char* tbuf, int tsi @@ -124,86 +124,6 @@ int parse_bytes(char* data, int size, char* hbuf, int hsize, char* tbuf, int tsi
124 } 124 }
125 } 125 }
126 126
127 -#define FLV_HEADER_SIZE 11  
128 -int parse_script_data(u_int32_t timestamp, u_int32_t pts, char* data, int size, int64_t offset)  
129 -{  
130 - int ret = 0;  
131 -  
132 - char hbuf[48];  
133 - char tbuf[48];  
134 -  
135 - int amf0_size = 0;  
136 - int nparsed = 0;  
137 -  
138 - srs_amf0_t amf0_name;  
139 - char* amf0_name_str = NULL;  
140 -  
141 - srs_amf0_t amf0_data;  
142 - char* amf0_data_str = NULL;  
143 -  
144 - // bytes  
145 - parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16);  
146 -  
147 - // amf0  
148 - amf0_name = srs_amf0_parse(data, size, &nparsed);  
149 - if (amf0_name == NULL || nparsed >= size) {  
150 - srs_lib_trace("invalid amf0 name data.");  
151 - return -1;  
152 - }  
153 - amf0_data = srs_amf0_parse(data + nparsed, size - nparsed, &nparsed);  
154 -  
155 - srs_lib_trace("packet type=%s, dts=%d, pts=%d, size=%d, data-size=%d, \n"  
156 - "offset=%d\n[+00, +15] %s\n[-15, EOF] %s\n%s%s",  
157 - srs_type2string(SRS_RTMP_TYPE_SCRIPT), timestamp, pts,  
158 - size + FLV_HEADER_SIZE, size, (int)offset, hbuf, tbuf,  
159 - srs_amf0_human_print(amf0_name, &amf0_name_str, &amf0_size),  
160 - srs_amf0_human_print(amf0_data, &amf0_data_str, &amf0_size));  
161 -  
162 - srs_amf0_free(amf0_name);  
163 - srs_amf0_free_bytes(amf0_name_str);  
164 -  
165 - srs_amf0_free(amf0_data);  
166 - srs_amf0_free_bytes(amf0_data_str);  
167 -  
168 - return ret;  
169 -}  
170 -  
171 -int parse_audio_data(u_int32_t timestamp, u_int32_t pts, char* data, int size, int64_t offset)  
172 -{  
173 - int ret = 0;  
174 -  
175 - char hbuf[48];  
176 - char tbuf[48];  
177 -  
178 - // bytes  
179 - parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16);  
180 -  
181 - srs_lib_trace("packet type=%s, dts=%d, pts=%d, size=%d, data-size=%d, \n"  
182 - "offset=%d\n[+00, +15] %s\n[-15, EOF] %s\n",  
183 - srs_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, pts,  
184 - size + FLV_HEADER_SIZE, size, (int)offset, hbuf, tbuf);  
185 -  
186 - return ret;  
187 -}  
188 -  
189 -int parse_video_data(u_int32_t timestamp, u_int32_t pts, char* data, int size, int64_t offset)  
190 -{  
191 - int ret = 0;  
192 -  
193 - char hbuf[48];  
194 - char tbuf[48];  
195 -  
196 - // bytes  
197 - parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16);  
198 -  
199 - srs_lib_trace("packet type=%s, dts=%d, pts=%d, size=%d, data-size=%d, \n"  
200 - "offset=%d\n[+00, +15] %s\n[-15, EOF] %s\n",  
201 - srs_type2string(SRS_RTMP_TYPE_VIDEO), timestamp, pts,  
202 - size + FLV_HEADER_SIZE, size, (int)offset, hbuf, tbuf);  
203 -  
204 - return ret;  
205 -}  
206 -  
207 int parse_flv(srs_flv_t flv) 127 int parse_flv(srs_flv_t flv)
208 { 128 {
209 int ret = 0; 129 int ret = 0;
@@ -240,19 +160,19 @@ int parse_flv(srs_flv_t flv) @@ -240,19 +160,19 @@ int parse_flv(srs_flv_t flv)
240 break; 160 break;
241 } 161 }
242 162
243 - u_int32_t pts = 0;  
244 data = (char*)malloc(size); 163 data = (char*)malloc(size);
245 164
246 - if ((ret = srs_flv_read_tag_data(flv, data, size)) == 0  
247 - && (ret = srs_parse_timestamp(timestamp, type, data, size, &pts)) == 0  
248 - ) {  
249 - if (type == SRS_RTMP_TYPE_AUDIO) {  
250 - ret = parse_audio_data(timestamp, pts, data, size, offset);  
251 - } else if (type == SRS_RTMP_TYPE_VIDEO) {  
252 - ret = parse_video_data(timestamp, pts, data, size, offset); 165 + if ((ret = srs_flv_read_tag_data(flv, data, size)) == 0) {
  166 + if ((ret = srs_print_rtmp_packet(type, timestamp, data, size)) == 0) {
  167 + char hbuf[48]; char tbuf[48];
  168 + parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16);
  169 + srs_raw_trace("offset=%d, first and last 16 bytes:\n"
  170 + "[+00, +15] %s\n[-15, EOF] %s\n", (int)offset, hbuf, tbuf);
253 } else { 171 } else {
254 - ret = parse_script_data(timestamp, pts, data, size, offset); 172 + srs_lib_trace("print packet failed. ret=%d", ret);
255 } 173 }
  174 + } else {
  175 + srs_lib_trace("read flv failed. ret=%d", ret);
256 } 176 }
257 177
258 free(data); 178 free(data);
@@ -141,12 +141,17 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u @@ -141,12 +141,17 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u
141 return ret; 141 return ret;
142 } 142 }
143 143
  144 + u_int32_t timestamp = *ptimestamp;
  145 +
  146 + if ((ret = srs_print_rtmp_packet(type, timestamp, data, size)) != 0) {
  147 + srs_lib_trace("print packet failed. ret=%d", ret);
  148 + return ret;
  149 + }
  150 +
144 if ((ret = srs_write_packet(ortmp, type, *ptimestamp, data, size)) != 0) { 151 if ((ret = srs_write_packet(ortmp, type, *ptimestamp, data, size)) != 0) {
145 srs_lib_trace("irtmp get packet failed. ret=%d", ret); 152 srs_lib_trace("irtmp get packet failed. ret=%d", ret);
146 return ret; 153 return ret;
147 } 154 }
148 - srs_lib_verbose("ortmp sent packet: type=%s, time=%d, size=%d",  
149 - srs_type2string(type), *ptimestamp, size);  
150 155
151 if (*pstarttime < 0) { 156 if (*pstarttime < 0) {
152 *pstarttime = *ptimestamp; 157 *pstarttime = *ptimestamp;
@@ -112,8 +112,11 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp) @@ -112,8 +112,11 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
112 srs_lib_trace("irtmp get packet failed. ret=%d", ret); 112 srs_lib_trace("irtmp get packet failed. ret=%d", ret);
113 return ret; 113 return ret;
114 } 114 }
115 - srs_lib_verbose("irtmp got packet: type=%s, time=%d, size=%d",  
116 - srs_type2string(type), timestamp, size); 115 +
  116 + if ((ret = srs_print_rtmp_packet(type, timestamp, data, size)) != 0) {
  117 + srs_lib_trace("print packet failed. ret=%d", ret);
  118 + return ret;
  119 + }
117 120
118 if ((ret = srs_write_packet(ortmp, type, timestamp, data, size)) != 0) { 121 if ((ret = srs_write_packet(ortmp, type, timestamp, data, size)) != 0) {
119 srs_lib_trace("irtmp get packet failed. ret=%d", ret); 122 srs_lib_trace("irtmp get packet failed. ret=%d", ret);
@@ -69,16 +69,15 @@ int main(int argc, char** argv) @@ -69,16 +69,15 @@ int main(int argc, char** argv)
69 int size; 69 int size;
70 char type; 70 char type;
71 char* data; 71 char* data;
72 - u_int32_t timestamp, pts; 72 + u_int32_t timestamp;
73 73
74 if (srs_read_packet(rtmp, &type, &timestamp, &data, &size) != 0) { 74 if (srs_read_packet(rtmp, &type, &timestamp, &data, &size) != 0) {
75 goto rtmp_destroy; 75 goto rtmp_destroy;
76 } 76 }
77 - if (srs_parse_timestamp(timestamp, type, data, size, &pts) != 0) { 77 +
  78 + if (srs_print_rtmp_packet(type, timestamp, data, size) != 0) {
78 goto rtmp_destroy; 79 goto rtmp_destroy;
79 } 80 }
80 - srs_lib_trace("got packet: type=%s, dts=%d, pts=%d, size=%d",  
81 - srs_type2string(type), timestamp, pts, size);  
82 81
83 free(data); 82 free(data);
84 } 83 }
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 27 34 +#define VERSION_REVISION 28
35 // server info. 35 // server info.
36 #define RTMP_SIG_SRS_KEY "SRS" 36 #define RTMP_SIG_SRS_KEY "SRS"
37 #define RTMP_SIG_SRS_ROLE "origin/edge server" 37 #define RTMP_SIG_SRS_ROLE "origin/edge server"
@@ -936,6 +936,161 @@ int srs_parse_timestamp( @@ -936,6 +936,161 @@ int srs_parse_timestamp(
936 return ret; 936 return ret;
937 } 937 }
938 938
  939 +char srs_get_codec_id(char* data, int size)
  940 +{
  941 + if (size < 1) {
  942 + return 0;
  943 + }
  944 +
  945 + char codec_id = data[0];
  946 + codec_id = codec_id & 0x0F;
  947 +
  948 + return codec_id;
  949 +}
  950 +
  951 +const char* srs_code_id2string(char codec_id)
  952 +{
  953 + static const char* h263 = "H.263";
  954 + static const char* screen = "Screen";
  955 + static const char* vp6 = "VP6";
  956 + static const char* vp6_alpha = "VP6Alpha";
  957 + static const char* screen2 = "Screen2";
  958 + static const char* h264 = "H.264";
  959 + static const char* unknown = "Unknown";
  960 +
  961 + switch (codec_id) {
  962 + case 2: return h263;
  963 + case 3: return screen;
  964 + case 4: return vp6;
  965 + case 5: return vp6_alpha;
  966 + case 6: return screen2;
  967 + case 7: return h264;
  968 + default: return unknown;
  969 + }
  970 +
  971 + return unknown;
  972 +}
  973 +
  974 +char srs_get_avc_packet_type(char* data, int size)
  975 +{
  976 + if (size < 2) {
  977 + return -1;
  978 + }
  979 +
  980 + if (!SrsFlvCodec::video_is_h264(data, size)) {
  981 + return -1;
  982 + }
  983 +
  984 + u_int8_t avc_packet_type = data[1];
  985 +
  986 + if (avc_packet_type > 2) {
  987 + return -1;
  988 + }
  989 +
  990 + return avc_packet_type;
  991 +}
  992 +
  993 +const char* srs_avc_packet2string(char avc_packet_type)
  994 +{
  995 + static const char* sps_pps = "SpsPps";
  996 + static const char* nalu = "Nalu";
  997 + static const char* sps_pps_end = "SpsPpsEnd";
  998 + static const char* unknown = "Unknown";
  999 +
  1000 + switch (avc_packet_type) {
  1001 + case 0: return sps_pps;
  1002 + case 1: return nalu;
  1003 + case 2: return sps_pps_end;
  1004 + default: return unknown;
  1005 + }
  1006 +
  1007 + return unknown;
  1008 +}
  1009 +
  1010 +char srs_get_frame_type(char* data, int size)
  1011 +{
  1012 + if (size < 1) {
  1013 + return -1;
  1014 + }
  1015 +
  1016 + if (!SrsFlvCodec::video_is_h264(data, size)) {
  1017 + return -1;
  1018 + }
  1019 +
  1020 + u_int8_t frame_type = data[0];
  1021 + frame_type = (frame_type >> 4) & 0x0f;
  1022 + if (frame_type < 1 || frame_type > 5) {
  1023 + return -1;
  1024 + }
  1025 +
  1026 + return frame_type;
  1027 +}
  1028 +
  1029 +const char* srs_frame_type2string(char frame_type)
  1030 +{
  1031 + static const char* keyframe = "I";
  1032 + static const char* interframe = "P/B";
  1033 + static const char* disposable_interframe = "DI";
  1034 + static const char* generated_keyframe = "GI";
  1035 + static const char* video_infoframe = "VI";
  1036 + static const char* unknown = "Unknown";
  1037 +
  1038 + switch (frame_type) {
  1039 + case 1: return keyframe;
  1040 + case 2: return interframe;
  1041 + case 3: return disposable_interframe;
  1042 + case 4: return generated_keyframe;
  1043 + case 5: return video_infoframe;
  1044 + default: return unknown;
  1045 + }
  1046 +
  1047 + return unknown;
  1048 +}
  1049 +
  1050 +int srs_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size)
  1051 +{
  1052 + int ret = ERROR_SUCCESS;
  1053 +
  1054 + u_int32_t pts;
  1055 + if (srs_parse_timestamp(timestamp, type, data, size, &pts) != 0) {
  1056 + return ret;
  1057 + }
  1058 +
  1059 + if (type == SRS_RTMP_TYPE_VIDEO) {
  1060 + srs_lib_trace("Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s)",
  1061 + srs_type2string(type), timestamp, pts, size,
  1062 + srs_code_id2string(srs_get_codec_id(data, size)),
  1063 + srs_avc_packet2string(srs_get_avc_packet_type(data, size)),
  1064 + srs_frame_type2string(srs_get_frame_type(data, size))
  1065 + );
  1066 + } else if (type == SRS_RTMP_TYPE_AUDIO) {
  1067 + srs_lib_trace("Audio packet type=%s, dts=%d, pts=%d, size=%d",
  1068 + srs_type2string(type), timestamp, pts, size);
  1069 + } else if (type == SRS_RTMP_TYPE_SCRIPT) {
  1070 + srs_lib_verbose("Data packet type=%s, time=%d, size=%d",
  1071 + srs_type2string(type), timestamp, size);
  1072 + int nparsed = 0;
  1073 + while (nparsed < size) {
  1074 + int nb_parsed_this = 0;
  1075 + srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this);
  1076 + if (amf0 == NULL) {
  1077 + break;
  1078 + }
  1079 +
  1080 + nparsed += nb_parsed_this;
  1081 +
  1082 + char* amf0_str = NULL;
  1083 + srs_raw_trace("%s", srs_amf0_human_print(amf0, &amf0_str, NULL));
  1084 + srs_amf0_free_bytes(amf0_str);
  1085 + }
  1086 + } else {
  1087 + srs_lib_trace("Unknown packet type=%s, dts=%d, pts=%d, size=%d",
  1088 + srs_type2string(type), timestamp, pts, size);
  1089 + }
  1090 +
  1091 + return ret;
  1092 +}
  1093 +
939 const char* srs_format_time() 1094 const char* srs_format_time()
940 { 1095 {
941 struct timeval tv; 1096 struct timeval tv;
@@ -1171,7 +1326,9 @@ srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) @@ -1171,7 +1326,9 @@ srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
1171 return amf0; 1326 return amf0;
1172 } 1327 }
1173 1328
1174 - *nparsed = stream.pos(); 1329 + if (nparsed) {
  1330 + *nparsed = stream.pos();
  1331 + }
1175 amf0 = (srs_amf0_t)any; 1332 amf0 = (srs_amf0_t)any;
1176 1333
1177 return amf0; 1334 return amf0;
@@ -1445,8 +1602,6 @@ int srs_audio_write_raw_frame(srs_rtmp_t rtmp, @@ -1445,8 +1602,6 @@ int srs_audio_write_raw_frame(srs_rtmp_t rtmp,
1445 char sound_format, char sound_rate, char sound_size, char sound_type, 1602 char sound_format, char sound_rate, char sound_size, char sound_type,
1446 char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp 1603 char aac_packet_type, char* frame, int frame_size, u_int32_t timestamp
1447 ) { 1604 ) {
1448 - int ret = ERROR_SUCCESS;  
1449 -  
1450 Context* context = (Context*)rtmp; 1605 Context* context = (Context*)rtmp;
1451 srs_assert(context); 1606 srs_assert(context);
1452 1607
@@ -273,9 +273,22 @@ extern int srs_version_revision(); @@ -273,9 +273,22 @@ extern int srs_version_revision();
273 * utilities 273 * utilities
274 ************************************************************** 274 **************************************************************
275 *************************************************************/ 275 *************************************************************/
  276 +/**
  277 +* get the current system time in ms.
  278 +* use gettimeofday() to get system time.
  279 +*/
276 extern int64_t srs_get_time_ms(); 280 extern int64_t srs_get_time_ms();
  281 +
  282 +/**
  283 +* get the send bytes.
  284 +*/
277 extern int64_t srs_get_nsend_bytes(srs_rtmp_t rtmp); 285 extern int64_t srs_get_nsend_bytes(srs_rtmp_t rtmp);
  286 +
  287 +/**
  288 +* get the recv bytes.
  289 +*/
278 extern int64_t srs_get_nrecv_bytes(srs_rtmp_t rtmp); 290 extern int64_t srs_get_nrecv_bytes(srs_rtmp_t rtmp);
  291 +
279 /** 292 /**
280 * parse the dts and pts by time in header and data in tag, 293 * parse the dts and pts by time in header and data in tag,
281 * or to parse the RTMP packet by srs_read_packet(). 294 * or to parse the RTMP packet by srs_read_packet().
@@ -296,10 +309,92 @@ extern int srs_parse_timestamp( @@ -296,10 +309,92 @@ extern int srs_parse_timestamp(
296 u_int32_t* ppts 309 u_int32_t* ppts
297 ); 310 );
298 311
  312 +/**
  313 +* get the CodecID of video tag.
  314 +* Codec Identifier. The following values are defined:
  315 +* 2 = Sorenson H.263
  316 +* 3 = Screen video
  317 +* 4 = On2 VP6
  318 +* 5 = On2 VP6 with alpha channel
  319 +* 6 = Screen video version 2
  320 +* 7 = AVC
  321 +* @return the code id. 0 for error.
  322 +*/
  323 +extern char srs_get_codec_id(char* data, int size);
  324 +
  325 +/**
  326 +* get the codec id string.
  327 +* H.263 = Sorenson H.263
  328 +* Screen = Screen video
  329 +* VP6 = On2 VP6
  330 +* VP6Alpha = On2 VP6 with alpha channel
  331 +* Screen2 = Screen video version 2
  332 +* H.264 = AVC
  333 +* otherwise, "Unknown"
  334 +* @remark user never free the return char*,
  335 +* it's static shared const string.
  336 +*/
  337 +extern const char* srs_code_id2string(char codec_id);
  338 +
  339 +/**
  340 +* get the AVCPacketType of video tag.
  341 +* The following values are defined:
  342 +* 0 = AVC sequence header
  343 +* 1 = AVC NALU
  344 +* 2 = AVC end of sequence (lower level NALU sequence ender is
  345 +* not required or supported)
  346 +* @return the avc packet type. -1(0xff) for error.
  347 +*/
  348 +extern char srs_get_avc_packet_type(char* data, int size);
  349 +
  350 +/**
  351 +* get the avc packet type string.
  352 +* SpsPps = AVC sequence header
  353 +* Nalu = AVC NALU
  354 +* SpsPpsEnd = AVC end of sequence
  355 +* otherwise, "Unknown"
  356 +* @remark user never free the return char*,
  357 +* it's static shared const string.
  358 +*/
  359 +extern const char* srs_avc_packet2string(char avc_packet_type);
  360 +
  361 +/**
  362 +* get the FrameType of video tag.
  363 +* Type of video frame. The following values are defined:
  364 +* 1 = key frame (for AVC, a seekable frame)
  365 +* 2 = inter frame (for AVC, a non-seekable frame)
  366 +* 3 = disposable inter frame (H.263 only)
  367 +* 4 = generated key frame (reserved for server use only)
  368 +* 5 = video info/command frame
  369 +* @return the frame type. 0 for error.
  370 +*/
  371 +extern char srs_get_frame_type(char* data, int size);
  372 +
  373 +/**
  374 +* get the frame type string.
  375 +* I = key frame (for AVC, a seekable frame)
  376 +* P/B = inter frame (for AVC, a non-seekable frame)
  377 +* DI = disposable inter frame (H.263 only)
  378 +* GI = generated key frame (reserved for server use only)
  379 +* VI = video info/command frame
  380 +* otherwise, "Unknown"
  381 +* @remark user never free the return char*,
  382 +* it's static shared const string.
  383 +*/
  384 +extern const char* srs_frame_type2string(char frame_type);
  385 +
  386 +/**
  387 +* print the rtmp packet, use srs_lib_trace/srs_lib_verbose for packet,
  388 +* and use srs_raw_trace for script data body.
  389 +* @return an error code for parse the timetstamp to dts and pts.
  390 +*/
  391 +extern int srs_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size);
  392 +
299 // log to console, for use srs-librtmp application. 393 // log to console, for use srs-librtmp application.
300 extern const char* srs_format_time(); 394 extern const char* srs_format_time();
301 #define srs_lib_trace(msg, ...) printf("[%s] ", srs_format_time());printf(msg, ##__VA_ARGS__);printf("\n") 395 #define srs_lib_trace(msg, ...) printf("[%s] ", srs_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
302 #define srs_lib_verbose(msg, ...) printf("[%s] ", srs_format_time());printf(msg, ##__VA_ARGS__);printf("\n") 396 #define srs_lib_verbose(msg, ...) printf("[%s] ", srs_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
  397 +#define srs_raw_trace(msg, ...) printf(msg, ##__VA_ARGS__)
303 398
304 /************************************************************* 399 /*************************************************************
305 ************************************************************** 400 **************************************************************
@@ -412,6 +507,11 @@ extern srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size); @@ -412,6 +507,11 @@ extern srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size);
412 typedef void* srs_amf0_t; 507 typedef void* srs_amf0_t;
413 typedef int srs_amf0_bool; 508 typedef int srs_amf0_bool;
414 typedef double srs_amf0_number; 509 typedef double srs_amf0_number;
  510 +/**
  511 +* parse amf0 from data.
  512 +* @param nparsed, the parsed size, NULL to ignore.
  513 +* @return the parsed amf0 object. NULL for error.
  514 +*/
415 extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed); 515 extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed);
416 extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value); 516 extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value);
417 extern srs_amf0_t srs_amf0_create_ecma_array(); 517 extern srs_amf0_t srs_amf0_create_ecma_array();