winlin

Merge branch 'srs.master'

@@ -244,6 +244,7 @@ Supported operating systems and hardware: @@ -244,6 +244,7 @@ Supported operating systems and hardware:
244 * 2013-10-17, Created.<br/> 244 * 2013-10-17, Created.<br/>
245 245
246 ## History 246 ## History
  247 +* v2.0, 2014-11-15, fix [#203](https://github.com/winlinvip/simple-rtmp-server/issues/203), srs-librtmp drop any video before sps/pps(sequence header). 2.0.21.
247 * v2.0, 2014-11-15, fix [#202](https://github.com/winlinvip/simple-rtmp-server/issues/202), fix memory leak of h.264 raw packet send in srs-librtmp. 2.0.20. 248 * v2.0, 2014-11-15, fix [#202](https://github.com/winlinvip/simple-rtmp-server/issues/202), fix memory leak of h.264 raw packet send in srs-librtmp. 2.0.20.
248 * v2.0, 2014-11-13, fix [#200](https://github.com/winlinvip/simple-rtmp-server/issues/200), deadloop when read/write 0 and ETIME. 2.0.16. 249 * v2.0, 2014-11-13, fix [#200](https://github.com/winlinvip/simple-rtmp-server/issues/200), deadloop when read/write 0 and ETIME. 2.0.16.
249 * v2.0, 2014-11-13, fix [#194](https://github.com/winlinvip/simple-rtmp-server/issues/194), writev multiple msgs, support 6k+ 250kbps clients. 2.0.15. 250 * v2.0, 2014-11-13, fix [#194](https://github.com/winlinvip/simple-rtmp-server/issues/194), writev multiple msgs, support 6k+ 250kbps clients. 2.0.15.
@@ -166,10 +166,15 @@ int main(int argc, char** argv) @@ -166,10 +166,15 @@ int main(int argc, char** argv)
166 } 166 }
167 167
168 // send out the h264 packet over RTMP 168 // send out the h264 packet over RTMP
169 - if (srs_write_h264_raw_frames(rtmp, data, size, dts, pts) != 0) { 169 + int error = srs_h264_write_raw_frames(rtmp, data, size, dts, pts);
  170 + if (error != 0) {
  171 + if (srs_h264_is_dvbsp_error(error)) {
  172 + srs_lib_trace("ignore drop video error, code=%d", error);
  173 + } else {
170 srs_lib_trace("send h264 raw data failed."); 174 srs_lib_trace("send h264 raw data failed.");
171 goto rtmp_destroy; 175 goto rtmp_destroy;
172 } 176 }
  177 + }
173 178
174 // 5bits, 7.3.1 NAL unit syntax, 179 // 5bits, 7.3.1 NAL unit syntax,
175 // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. 180 // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
@@ -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 20 34 +#define VERSION_REVISION 21
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"
@@ -186,6 +186,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -186,6 +186,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
186 #define ERROR_HLS_AVC_TRY_OTHERS 3040 186 #define ERROR_HLS_AVC_TRY_OTHERS 3040
187 #define ERROR_H264_API_NO_PREFIXED 3041 187 #define ERROR_H264_API_NO_PREFIXED 3041
188 #define ERROR_FLV_INVALID_VIDEO_TAG 3042 188 #define ERROR_FLV_INVALID_VIDEO_TAG 3042
  189 +#define ERROR_H264_DROP_BEFORE_SPS_PPS 3043
189 190
190 /** 191 /**
191 * whether the error code is an system control error. 192 * whether the error code is an system control error.
@@ -76,11 +76,15 @@ struct Context @@ -76,11 +76,15 @@ struct Context
76 // about SPS, @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62 76 // about SPS, @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62
77 std::string h264_sps; 77 std::string h264_sps;
78 std::string h264_pps; 78 std::string h264_pps;
  79 + // whether the sps and pps sent,
  80 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
  81 + bool h264_sps_pps_sent;
79 82
80 Context() { 83 Context() {
81 rtmp = NULL; 84 rtmp = NULL;
82 skt = NULL; 85 skt = NULL;
83 stream_id = 0; 86 stream_id = 0;
  87 + h264_sps_pps_sent = false;
84 } 88 }
85 virtual ~Context() { 89 virtual ~Context() {
86 srs_freep(rtmp); 90 srs_freep(rtmp);
@@ -767,17 +771,17 @@ void srs_flv_lseek(srs_flv_t flv, int64_t offset) @@ -767,17 +771,17 @@ void srs_flv_lseek(srs_flv_t flv, int64_t offset)
767 context->reader.lseek(offset); 771 context->reader.lseek(offset);
768 } 772 }
769 773
770 -flv_bool srs_flv_is_eof(int error_code) 774 +srs_flv_bool srs_flv_is_eof(int error_code)
771 { 775 {
772 return error_code == ERROR_SYSTEM_FILE_EOF; 776 return error_code == ERROR_SYSTEM_FILE_EOF;
773 } 777 }
774 778
775 -flv_bool srs_flv_is_sequence_header(char* data, int32_t size) 779 +srs_flv_bool srs_flv_is_sequence_header(char* data, int32_t size)
776 { 780 {
777 return SrsFlvCodec::video_is_sequence_header(data, (int)size); 781 return SrsFlvCodec::video_is_sequence_header(data, (int)size);
778 } 782 }
779 783
780 -flv_bool srs_flv_is_keyframe(char* data, int32_t size) 784 +srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size)
781 { 785 {
782 return SrsFlvCodec::video_is_keyframe(data, (int)size); 786 return SrsFlvCodec::video_is_keyframe(data, (int)size);
783 } 787 }
@@ -1205,6 +1209,7 @@ int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts) @@ -1205,6 +1209,7 @@ int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts)
1205 // reset sps and pps. 1209 // reset sps and pps.
1206 context->h264_pps = ""; 1210 context->h264_pps = "";
1207 context->h264_sps = ""; 1211 context->h264_sps = "";
  1212 + context->h264_sps_pps_sent = true;
1208 1213
1209 // TODO: FIXME: for more profile. 1214 // TODO: FIXME: for more profile.
1210 // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 1215 // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
@@ -1227,6 +1232,12 @@ int __srs_write_h264_ipb_frame(Context* context, @@ -1227,6 +1232,12 @@ int __srs_write_h264_ipb_frame(Context* context,
1227 ) { 1232 ) {
1228 int ret = ERROR_SUCCESS; 1233 int ret = ERROR_SUCCESS;
1229 1234
  1235 + // when sps or pps not sent, ignore the packet.
  1236 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
  1237 + if (!context->h264_sps_pps_sent) {
  1238 + return ERROR_H264_DROP_BEFORE_SPS_PPS;
  1239 + }
  1240 +
1230 // 5bits, 7.3.1 NAL unit syntax, 1241 // 5bits, 7.3.1 NAL unit syntax,
1231 // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. 1242 // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
1232 // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame 1243 // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
@@ -1315,7 +1326,7 @@ int __srs_write_h264_raw_frame(Context* context, @@ -1315,7 +1326,7 @@ int __srs_write_h264_raw_frame(Context* context,
1315 /** 1326 /**
1316 * write h264 multiple frames, in annexb format. 1327 * write h264 multiple frames, in annexb format.
1317 */ 1328 */
1318 -int srs_write_h264_raw_frames(srs_rtmp_t rtmp, 1329 +int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
1319 char* frames, int frames_size, u_int32_t dts, u_int32_t pts 1330 char* frames, int frames_size, u_int32_t dts, u_int32_t pts
1320 ) { 1331 ) {
1321 int ret = ERROR_SUCCESS; 1332 int ret = ERROR_SUCCESS;
@@ -1360,6 +1371,11 @@ int srs_write_h264_raw_frames(srs_rtmp_t rtmp, @@ -1360,6 +1371,11 @@ int srs_write_h264_raw_frames(srs_rtmp_t rtmp,
1360 return ret; 1371 return ret;
1361 } 1372 }
1362 1373
  1374 +srs_h264_bool srs_h264_is_dvbsp_error(int error_code)
  1375 +{
  1376 + return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS;
  1377 +}
  1378 +
1363 int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code) 1379 int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)
1364 { 1380 {
1365 SrsStream stream; 1381 SrsStream stream;
@@ -269,7 +269,7 @@ extern const char* srs_format_time(); @@ -269,7 +269,7 @@ extern const char* srs_format_time();
269 ************************************************************** 269 **************************************************************
270 *************************************************************/ 270 *************************************************************/
271 typedef void* srs_flv_t; 271 typedef void* srs_flv_t;
272 -typedef int flv_bool; 272 +typedef int srs_flv_bool;
273 /* open flv file for both read/write. */ 273 /* open flv file for both read/write. */
274 extern srs_flv_t srs_flv_open_read(const char* file); 274 extern srs_flv_t srs_flv_open_read(const char* file);
275 extern srs_flv_t srs_flv_open_write(const char* file); 275 extern srs_flv_t srs_flv_open_write(const char* file);
@@ -344,20 +344,20 @@ extern int64_t srs_flv_tellg(srs_flv_t flv); @@ -344,20 +344,20 @@ extern int64_t srs_flv_tellg(srs_flv_t flv);
344 extern void srs_flv_lseek(srs_flv_t flv, int64_t offset); 344 extern void srs_flv_lseek(srs_flv_t flv, int64_t offset);
345 /* error code */ 345 /* error code */
346 /* whether the error code indicates EOF */ 346 /* whether the error code indicates EOF */
347 -extern flv_bool srs_flv_is_eof(int error_code); 347 +extern srs_flv_bool srs_flv_is_eof(int error_code);
348 /* media codec */ 348 /* media codec */
349 /** 349 /**
350 * whether the video body is sequence header 350 * whether the video body is sequence header
351 * @param data, the data of tag, read by srs_flv_read_tag_data(). 351 * @param data, the data of tag, read by srs_flv_read_tag_data().
352 * @param size, the size of tag, read by srs_flv_read_tag_data(). 352 * @param size, the size of tag, read by srs_flv_read_tag_data().
353 */ 353 */
354 -extern flv_bool srs_flv_is_sequence_header(char* data, int32_t size); 354 +extern srs_flv_bool srs_flv_is_sequence_header(char* data, int32_t size);
355 /** 355 /**
356 * whether the video body is keyframe 356 * whether the video body is keyframe
357 * @param data, the data of tag, read by srs_flv_read_tag_data(). 357 * @param data, the data of tag, read by srs_flv_read_tag_data().
358 * @param size, the size of tag, read by srs_flv_read_tag_data(). 358 * @param size, the size of tag, read by srs_flv_read_tag_data().
359 */ 359 */
360 -extern flv_bool srs_flv_is_keyframe(char* data, int32_t size); 360 +extern srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size);
361 361
362 /************************************************************* 362 /*************************************************************
363 ************************************************************** 363 **************************************************************
@@ -424,6 +424,7 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); @@ -424,6 +424,7 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
424 * h264 raw codec 424 * h264 raw codec
425 ************************************************************** 425 **************************************************************
426 *************************************************************/ 426 *************************************************************/
  427 +typedef int srs_h264_bool;
427 /** 428 /**
428 * write h.264 raw frame over RTMP to rtmp server. 429 * write h.264 raw frame over RTMP to rtmp server.
429 * @param frames the input h264 raw data, encoded h.264 I/P/B frames data. 430 * @param frames the input h264 raw data, encoded h.264 I/P/B frames data.
@@ -441,8 +442,10 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize); @@ -441,8 +442,10 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
441 * @remark, cts = pts - dts 442 * @remark, cts = pts - dts
442 * @remark, use srs_h264_startswith_annexb to check whether frame is annexb format. 443 * @remark, use srs_h264_startswith_annexb to check whether frame is annexb format.
443 * @example /trunk/research/librtmp/srs_h264_raw_publish.c 444 * @example /trunk/research/librtmp/srs_h264_raw_publish.c
  445 +* @see https://github.com/winlinvip/simple-rtmp-server/issues/66
444 * 446 *
445 * @return 0, success; otherswise, failed. 447 * @return 0, success; otherswise, failed.
  448 +* for dvbsp error, check by srs_h264_is_dvbsp_error(error_code).
446 */ 449 */
447 /** 450 /**
448 For the example file: 451 For the example file:
@@ -458,25 +461,36 @@ The data sequence is: @@ -458,25 +461,36 @@ The data sequence is:
458 0000000141E02041F8CDDC562BBDEFAD2F..... 461 0000000141E02041F8CDDC562BBDEFAD2F.....
459 User can send the SPS+PPS, then each frame: 462 User can send the SPS+PPS, then each frame:
460 // SPS+PPS 463 // SPS+PPS
461 - srs_write_h264_raw_frame('000000016742802995A014016E400000000168CE3880', size, dts, pts) 464 + srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts)
462 // IFrame 465 // IFrame
463 - srs_write_h264_raw_frame('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) 466 + srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts)
464 // PFrame 467 // PFrame
465 - srs_write_h264_raw_frame('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) 468 + srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts)
466 User also can send one by one: 469 User also can send one by one:
467 // SPS 470 // SPS
468 - srs_write_h264_raw_frame('000000016742802995A014016E4', size, dts, pts) 471 + srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts)
469 // PPS 472 // PPS
470 - srs_write_h264_raw_frame('00000000168CE3880', size, dts, pts) 473 + srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts)
471 // IFrame 474 // IFrame
472 - srs_write_h264_raw_frame('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) 475 + srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts)
473 // PFrame 476 // PFrame
474 - srs_write_h264_raw_frame('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) 477 + srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts)
475 */ 478 */
476 -extern int srs_write_h264_raw_frames(srs_rtmp_t rtmp, 479 +extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
477 char* frames, int frames_size, u_int32_t dts, u_int32_t pts 480 char* frames, int frames_size, u_int32_t dts, u_int32_t pts
478 ); 481 );
479 /** 482 /**
  483 +* whether error_code is dvbsp(drop video before sps/pps/sequence-header) error.
  484 +*
  485 +* @see https://github.com/winlinvip/simple-rtmp-server/issues/203
  486 +* @example /trunk/research/librtmp/srs_h264_raw_publish.c
  487 +* @remark why drop video?
  488 +* some encoder, for example, ipcamera, will send sps/pps before each IFrame,
  489 +* so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header),
  490 +* this will cause SRS server to disable HLS.
  491 +*/
  492 +extern srs_h264_bool srs_h264_is_dvbsp_error(int error_code);
  493 +/**
480 * whether h264 raw data starts with the annexb, 494 * whether h264 raw data starts with the annexb,
481 * which bytes sequence matches N[00] 00 00 01, where N>=0. 495 * which bytes sequence matches N[00] 00 00 01, where N>=0.
482 * @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data. 496 * @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data.