mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix #203, srs-librtmp drop any video before sps/pps(sequence header). 2.0.21.
This commit is contained in:
parent
ecfbcd68d8
commit
278ff845d3
6 changed files with 50 additions and 13 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 [#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.
|
||||||
* 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.
|
* 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,9 +166,14 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send out the h264 packet over RTMP
|
// send out the h264 packet over RTMP
|
||||||
if (srs_write_h264_raw_frames(rtmp, data, size, dts, pts) != 0) {
|
int error = srs_h264_write_raw_frames(rtmp, data, size, dts, pts);
|
||||||
srs_lib_trace("send h264 raw data failed.");
|
if (error != 0) {
|
||||||
goto rtmp_destroy;
|
if (srs_h264_is_dvbsp_error(error)) {
|
||||||
|
srs_lib_trace("ignore drop video error, code=%d", error);
|
||||||
|
} else {
|
||||||
|
srs_lib_trace("send h264 raw data failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5bits, 7.3.1 NAL unit syntax,
|
// 5bits, 7.3.1 NAL unit syntax,
|
||||||
|
|
|
@ -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 20
|
#define VERSION_REVISION 21
|
||||||
// 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"
|
||||||
|
|
|
@ -186,6 +186,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define ERROR_HLS_AVC_TRY_OTHERS 3040
|
#define ERROR_HLS_AVC_TRY_OTHERS 3040
|
||||||
#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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether the error code is an system control error.
|
* whether the error code is an system control error.
|
||||||
|
|
|
@ -76,11 +76,15 @@ struct Context
|
||||||
// about SPS, @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62
|
// about SPS, @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62
|
||||||
std::string h264_sps;
|
std::string h264_sps;
|
||||||
std::string h264_pps;
|
std::string h264_pps;
|
||||||
|
// whether the sps and pps sent,
|
||||||
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/203
|
||||||
|
bool h264_sps_pps_sent;
|
||||||
|
|
||||||
Context() {
|
Context() {
|
||||||
rtmp = NULL;
|
rtmp = NULL;
|
||||||
skt = NULL;
|
skt = NULL;
|
||||||
stream_id = 0;
|
stream_id = 0;
|
||||||
|
h264_sps_pps_sent = false;
|
||||||
}
|
}
|
||||||
virtual ~Context() {
|
virtual ~Context() {
|
||||||
srs_freep(rtmp);
|
srs_freep(rtmp);
|
||||||
|
@ -1205,6 +1209,7 @@ 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_pps = "";
|
||||||
context->h264_sps = "";
|
context->h264_sps = "";
|
||||||
|
context->h264_sps_pps_sent = true;
|
||||||
|
|
||||||
// TODO: FIXME: for more profile.
|
// TODO: FIXME: for more profile.
|
||||||
// 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
|
// 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,
|
||||||
) {
|
) {
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// when sps or pps not sent, ignore the packet.
|
||||||
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/203
|
||||||
|
if (!context->h264_sps_pps_sent) {
|
||||||
|
return ERROR_H264_DROP_BEFORE_SPS_PPS;
|
||||||
|
}
|
||||||
|
|
||||||
// 5bits, 7.3.1 NAL unit syntax,
|
// 5bits, 7.3.1 NAL unit syntax,
|
||||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||||
|
@ -1315,7 +1326,7 @@ int __srs_write_h264_raw_frame(Context* context,
|
||||||
/**
|
/**
|
||||||
* write h264 multiple frames, in annexb format.
|
* write h264 multiple frames, in annexb format.
|
||||||
*/
|
*/
|
||||||
int srs_write_h264_raw_frames(srs_rtmp_t rtmp,
|
int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
|
||||||
char* frames, int frames_size, u_int32_t dts, u_int32_t pts
|
char* frames, int frames_size, u_int32_t dts, u_int32_t pts
|
||||||
) {
|
) {
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -1360,6 +1371,11 @@ int srs_write_h264_raw_frames(srs_rtmp_t rtmp,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srs_h264_bool srs_h264_is_dvbsp_error(int error_code)
|
||||||
|
{
|
||||||
|
return error_code == ERROR_H264_DROP_BEFORE_SPS_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;
|
||||||
|
|
|
@ -424,6 +424,7 @@ extern char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
|
||||||
* h264 raw codec
|
* h264 raw codec
|
||||||
**************************************************************
|
**************************************************************
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
typedef int srs_h264_bool;
|
||||||
/**
|
/**
|
||||||
* write h.264 raw frame over RTMP to rtmp server.
|
* write h.264 raw frame over RTMP to rtmp server.
|
||||||
* @param frames the input h264 raw data, encoded h.264 I/P/B frames data.
|
* @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);
|
||||||
* @remark, cts = pts - dts
|
* @remark, cts = pts - dts
|
||||||
* @remark, use srs_h264_startswith_annexb to check whether frame is annexb format.
|
* @remark, use srs_h264_startswith_annexb to check whether frame is annexb format.
|
||||||
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
|
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
|
||||||
|
* @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 the example file:
|
For the example file:
|
||||||
|
@ -458,25 +461,36 @@ The data sequence is:
|
||||||
0000000141E02041F8CDDC562BBDEFAD2F.....
|
0000000141E02041F8CDDC562BBDEFAD2F.....
|
||||||
User can send the SPS+PPS, then each frame:
|
User can send the SPS+PPS, then each frame:
|
||||||
// SPS+PPS
|
// SPS+PPS
|
||||||
srs_write_h264_raw_frame('000000016742802995A014016E400000000168CE3880', size, dts, pts)
|
srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts)
|
||||||
// IFrame
|
// IFrame
|
||||||
srs_write_h264_raw_frame('0000000165B8041014C038008B0D0D3A071......', size, dts, pts)
|
srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts)
|
||||||
// PFrame
|
// PFrame
|
||||||
srs_write_h264_raw_frame('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts)
|
srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts)
|
||||||
User also can send one by one:
|
User also can send one by one:
|
||||||
// SPS
|
// SPS
|
||||||
srs_write_h264_raw_frame('000000016742802995A014016E4', size, dts, pts)
|
srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts)
|
||||||
// PPS
|
// PPS
|
||||||
srs_write_h264_raw_frame('00000000168CE3880', size, dts, pts)
|
srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts)
|
||||||
// IFrame
|
// IFrame
|
||||||
srs_write_h264_raw_frame('0000000165B8041014C038008B0D0D3A071......', size, dts, pts)
|
srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts)
|
||||||
// PFrame
|
// PFrame
|
||||||
srs_write_h264_raw_frame('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts)
|
srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts)
|
||||||
*/
|
*/
|
||||||
extern int srs_write_h264_raw_frames(srs_rtmp_t rtmp,
|
extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp,
|
||||||
char* frames, int frames_size, u_int32_t dts, u_int32_t pts
|
char* frames, int frames_size, u_int32_t dts, u_int32_t pts
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
|
* whether error_code is dvbsp(drop video before sps/pps/sequence-header) error.
|
||||||
|
*
|
||||||
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/203
|
||||||
|
* @example /trunk/research/librtmp/srs_h264_raw_publish.c
|
||||||
|
* @remark why drop video?
|
||||||
|
* some encoder, for example, ipcamera, will send sps/pps before each IFrame,
|
||||||
|
* so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header),
|
||||||
|
* this will cause SRS server to disable HLS.
|
||||||
|
*/
|
||||||
|
extern srs_h264_bool srs_h264_is_dvbsp_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