mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	fix #204, srs-librtmp drop dupliated sps/pps(sequence header). 2.0.22.
This commit is contained in:
		
							parent
							
								
									b4269c8d67
								
							
						
					
					
						commit
						2c601a0069
					
				
					 6 changed files with 80 additions and 11 deletions
				
			
		| 
						 | 
					@ -244,6 +244,7 @@ Supported operating systems and hardware:
 | 
				
			||||||
* 2013-10-17, Created.<br/>
 | 
					* 2013-10-17, Created.<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## History
 | 
					## History
 | 
				
			||||||
 | 
					* v2.0, 2014-11-15, fix [#204](https://github.com/winlinvip/simple-rtmp-server/issues/204), srs-librtmp drop dupliated sps/pps(sequence header). 2.0.22.
 | 
				
			||||||
* 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.
 | 
					* 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.
 | 
				
			||||||
* 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.
 | 
					* 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.
 | 
				
			||||||
* 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.
 | 
					* 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.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,6 +170,10 @@ int main(int argc, char** argv)
 | 
				
			||||||
        if (error != 0) {
 | 
					        if (error != 0) {
 | 
				
			||||||
            if (srs_h264_is_dvbsp_error(error)) {
 | 
					            if (srs_h264_is_dvbsp_error(error)) {
 | 
				
			||||||
                srs_lib_trace("ignore drop video error, code=%d", error);
 | 
					                srs_lib_trace("ignore drop video error, code=%d", error);
 | 
				
			||||||
 | 
					            } else if (srs_h264_is_duplicated_sps_error(error)) {
 | 
				
			||||||
 | 
					                srs_lib_trace("ignore duplicated sps, code=%d", error);
 | 
				
			||||||
 | 
					            } else if (srs_h264_is_duplicated_pps_error(error)) {
 | 
				
			||||||
 | 
					                srs_lib_trace("ignore duplicated pps, code=%d", error);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                srs_lib_trace("send h264 raw data failed.");
 | 
					                srs_lib_trace("send h264 raw data failed.");
 | 
				
			||||||
                goto rtmp_destroy;
 | 
					                goto rtmp_destroy;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
// current release version
 | 
					// current release version
 | 
				
			||||||
#define VERSION_MAJOR       2
 | 
					#define VERSION_MAJOR       2
 | 
				
			||||||
#define VERSION_MINOR       0
 | 
					#define VERSION_MINOR       0
 | 
				
			||||||
#define VERSION_REVISION    21
 | 
					#define VERSION_REVISION    22
 | 
				
			||||||
// server info.
 | 
					// server info.
 | 
				
			||||||
#define RTMP_SIG_SRS_KEY "SRS"
 | 
					#define RTMP_SIG_SRS_KEY "SRS"
 | 
				
			||||||
#define RTMP_SIG_SRS_ROLE "origin/edge server"
 | 
					#define RTMP_SIG_SRS_ROLE "origin/edge server"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,6 +187,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
#define ERROR_H264_API_NO_PREFIXED          3041
 | 
					#define ERROR_H264_API_NO_PREFIXED          3041
 | 
				
			||||||
#define ERROR_FLV_INVALID_VIDEO_TAG         3042
 | 
					#define ERROR_FLV_INVALID_VIDEO_TAG         3042
 | 
				
			||||||
#define ERROR_H264_DROP_BEFORE_SPS_PPS      3043
 | 
					#define ERROR_H264_DROP_BEFORE_SPS_PPS      3043
 | 
				
			||||||
 | 
					#define ERROR_H264_DUPLICATED_SPS           3044
 | 
				
			||||||
 | 
					#define ERROR_H264_DUPLICATED_PPS           3045
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
* whether the error code is an system control error.
 | 
					* whether the error code is an system control error.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,12 +79,18 @@ struct Context
 | 
				
			||||||
    // whether the sps and pps sent,
 | 
					    // whether the sps and pps sent,
 | 
				
			||||||
    // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
 | 
				
			||||||
    bool h264_sps_pps_sent;
 | 
					    bool h264_sps_pps_sent;
 | 
				
			||||||
 | 
					    // only send the ssp and pps when both changed.
 | 
				
			||||||
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/204
 | 
				
			||||||
 | 
					    bool h264_sps_changed;
 | 
				
			||||||
 | 
					    bool h264_pps_changed;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Context() {
 | 
					    Context() {
 | 
				
			||||||
        rtmp = NULL;
 | 
					        rtmp = NULL;
 | 
				
			||||||
        skt = NULL;
 | 
					        skt = NULL;
 | 
				
			||||||
        stream_id = 0;
 | 
					        stream_id = 0;
 | 
				
			||||||
        h264_sps_pps_sent = false;
 | 
					        h264_sps_pps_sent = false;
 | 
				
			||||||
 | 
					        h264_sps_changed = false;
 | 
				
			||||||
 | 
					        h264_pps_changed = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtual ~Context() {
 | 
					    virtual ~Context() {
 | 
				
			||||||
        srs_freep(rtmp);
 | 
					        srs_freep(rtmp);
 | 
				
			||||||
| 
						 | 
					@ -1127,8 +1133,8 @@ int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = ERROR_SUCCESS;
 | 
					    int ret = ERROR_SUCCESS;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // when pps or sps not ready, ignore.
 | 
					    // only send when both sps and pps changed.
 | 
				
			||||||
    if (context->h264_pps.empty() || context->h264_sps.empty()) {
 | 
					    if (!context->h264_sps_changed || !context->h264_pps_changed) {
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -1207,8 +1213,8 @@ int __srs_write_h264_sps_pps(Context* context, u_int32_t dts, u_int32_t pts)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // reset sps and pps.
 | 
					    // reset sps and pps.
 | 
				
			||||||
    context->h264_pps = "";
 | 
					    context->h264_sps_changed = false;
 | 
				
			||||||
    context->h264_sps = "";
 | 
					    context->h264_pps_changed = false;
 | 
				
			||||||
    context->h264_sps_pps_sent = true;
 | 
					    context->h264_sps_pps_sent = true;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // TODO: FIXME: for more profile.
 | 
					    // TODO: FIXME: for more profile.
 | 
				
			||||||
| 
						 | 
					@ -1307,13 +1313,26 @@ int __srs_write_h264_raw_frame(Context* context,
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        context->h264_sps = "";
 | 
					        std::string sps;
 | 
				
			||||||
        context->h264_sps.append(frame, frame_size);
 | 
					        sps.append(frame, frame_size);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (context->h264_sps == sps) {
 | 
				
			||||||
 | 
					            return ERROR_H264_DUPLICATED_SPS;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        context->h264_sps_changed = true;
 | 
				
			||||||
 | 
					        context->h264_sps = sps;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return __srs_write_h264_sps_pps(context, dts, pts);
 | 
					        return __srs_write_h264_sps_pps(context, dts, pts);
 | 
				
			||||||
    } else if (nal_unit_type == 8) {
 | 
					    } else if (nal_unit_type == 8) {
 | 
				
			||||||
        context->h264_pps = "";
 | 
					        
 | 
				
			||||||
        context->h264_pps.append(frame, frame_size);
 | 
					        std::string pps;
 | 
				
			||||||
 | 
					        pps.append(frame, frame_size);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (context->h264_pps == pps) {
 | 
				
			||||||
 | 
					            return ERROR_H264_DUPLICATED_PPS;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        context->h264_pps_changed = true;
 | 
				
			||||||
 | 
					        context->h264_pps = pps;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return __srs_write_h264_sps_pps(context, dts, pts);
 | 
					        return __srs_write_h264_sps_pps(context, dts, pts);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					@ -1341,6 +1360,11 @@ int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    // use the last error
 | 
				
			||||||
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/203
 | 
				
			||||||
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/204
 | 
				
			||||||
 | 
					    int error_code_return = ret;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    // send each frame.
 | 
					    // send each frame.
 | 
				
			||||||
    while (!context->h264_raw_stream.empty()) {
 | 
					    while (!context->h264_raw_stream.empty()) {
 | 
				
			||||||
        // each frame must prefixed by annexb format.
 | 
					        // each frame must prefixed by annexb format.
 | 
				
			||||||
| 
						 | 
					@ -1363,12 +1387,24 @@ int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // send out the frame.
 | 
					        // send out the frame.
 | 
				
			||||||
        char* frame = context->h264_raw_stream.data() + start;
 | 
					        char* frame = context->h264_raw_stream.data() + start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // it may be return error, but we must process all packets.
 | 
				
			||||||
        if ((ret = __srs_write_h264_raw_frame(context, frame, size, dts, pts)) != ERROR_SUCCESS) {
 | 
					        if ((ret = __srs_write_h264_raw_frame(context, frame, size, dts, pts)) != ERROR_SUCCESS) {
 | 
				
			||||||
 | 
					            error_code_return = ret;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // ignore known error, process all packets.
 | 
				
			||||||
 | 
					            if (srs_h264_is_dvbsp_error(ret)
 | 
				
			||||||
 | 
					                || srs_h264_is_duplicated_sps_error(ret)
 | 
				
			||||||
 | 
					                || srs_h264_is_duplicated_pps_error(ret)
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return ret;
 | 
					    return error_code_return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
srs_h264_bool srs_h264_is_dvbsp_error(int error_code)
 | 
					srs_h264_bool srs_h264_is_dvbsp_error(int error_code)
 | 
				
			||||||
| 
						 | 
					@ -1376,6 +1412,16 @@ srs_h264_bool srs_h264_is_dvbsp_error(int error_code)
 | 
				
			||||||
    return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS;
 | 
					    return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					srs_h264_bool srs_h264_is_duplicated_sps_error(int error_code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return error_code == ERROR_H264_DUPLICATED_SPS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					srs_h264_bool srs_h264_is_duplicated_pps_error(int error_code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return error_code == ERROR_H264_DUPLICATED_PPS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)
 | 
					int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SrsStream stream;
 | 
					    SrsStream stream;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -445,7 +445,9 @@ typedef int srs_h264_bool;
 | 
				
			||||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/66
 | 
					* @see https://github.com/winlinvip/simple-rtmp-server/issues/66
 | 
				
			||||||
* 
 | 
					* 
 | 
				
			||||||
* @return 0, success; otherswise, failed.
 | 
					* @return 0, success; otherswise, failed.
 | 
				
			||||||
*       for dvbsp error, check by srs_h264_is_dvbsp_error(error_code).
 | 
					*       for dvbsp error, @see srs_h264_is_dvbsp_error().
 | 
				
			||||||
 | 
					*       for duplictated sps error, @see srs_h264_is_duplicated_sps_error().
 | 
				
			||||||
 | 
					*       for duplictated pps error, @see srs_h264_is_duplicated_pps_error().
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
For the example file: 
 | 
					For the example file: 
 | 
				
			||||||
| 
						 | 
					@ -491,6 +493,20 @@ extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
extern srs_h264_bool srs_h264_is_dvbsp_error(int error_code);
 | 
					extern srs_h264_bool srs_h264_is_dvbsp_error(int error_code);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
					* whether error_code is duplicated sps error.
 | 
				
			||||||
 | 
					* 
 | 
				
			||||||
 | 
					* @see https://github.com/winlinvip/simple-rtmp-server/issues/204
 | 
				
			||||||
 | 
					* @example /trunk/research/librtmp/srs_h264_raw_publish.c
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					extern srs_h264_bool srs_h264_is_duplicated_sps_error(int error_code);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					* whether error_code is duplicated pps error.
 | 
				
			||||||
 | 
					* 
 | 
				
			||||||
 | 
					* @see https://github.com/winlinvip/simple-rtmp-server/issues/204
 | 
				
			||||||
 | 
					* @example /trunk/research/librtmp/srs_h264_raw_publish.c
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					extern srs_h264_bool srs_h264_is_duplicated_pps_error(int error_code);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
* whether h264 raw data starts with the annexb,
 | 
					* whether h264 raw data starts with the annexb,
 | 
				
			||||||
* which bytes sequence matches N[00] 00 00 01, where N>=0.
 | 
					* which bytes sequence matches N[00] 00 00 01, where N>=0.
 | 
				
			||||||
* @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data.
 | 
					* @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue