mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
refine the h264 parser, one ts message should parsed to one rtmp/flv message.
This commit is contained in:
parent
4329366c08
commit
61d5b78ae5
8 changed files with 71 additions and 43 deletions
|
@ -355,12 +355,20 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
|
|||
if ((ret = avc->annexb_demux(avs, &frame, &frame_size)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ignore invalid frame,
|
||||
// * atleast 1bytes for SPS to decode the type
|
||||
// * ignore the auth bytes '09f0'
|
||||
if (frame_size <= 2) {
|
||||
continue;
|
||||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);
|
||||
|
||||
// ignore the nalu type sps(7), pps(8), aud(9)
|
||||
switch (nal_unit_type) {
|
||||
case SrsAvcNaluTypeSPS:
|
||||
case SrsAvcNaluTypePPS:
|
||||
case SrsAvcNaluTypeAccessUnitDelimiter:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// for sps
|
||||
|
@ -402,6 +410,7 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs)
|
|||
}
|
||||
|
||||
// ibp frame.
|
||||
// TODO: FIXME: we should group all frames to a rtmp/flv message from one ts message.
|
||||
srs_info("mpegts: demux avc ibp frame size=%d, dts=%d", ibpframe_size, dts);
|
||||
if ((ret = write_h264_ipb_frame(frame, frame_size, dts, pts)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -458,10 +467,20 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, u_int32_
|
|||
if (!h264_sps_pps_sent) {
|
||||
return ERROR_H264_DROP_BEFORE_SPS_PPS;
|
||||
}
|
||||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);
|
||||
|
||||
// for IDR frame, the frame is keyframe.
|
||||
SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame;
|
||||
if (nal_unit_type == SrsAvcNaluTypeIDR) {
|
||||
frame_type = SrsCodecVideoAVCFrameKeyFrame;
|
||||
}
|
||||
|
||||
std::string ibp;
|
||||
int8_t frame_type;
|
||||
if ((ret = avc->mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) {
|
||||
if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -579,10 +579,20 @@ int SrsRtspConn::write_h264_sps_pps(u_int32_t dts, u_int32_t pts)
|
|||
int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);
|
||||
|
||||
// for IDR frame, the frame is keyframe.
|
||||
SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame;
|
||||
if (nal_unit_type == SrsAvcNaluTypeIDR) {
|
||||
frame_type = SrsCodecVideoAVCFrameKeyFrame;
|
||||
}
|
||||
|
||||
std::string ibp;
|
||||
int8_t frame_type;
|
||||
if ((ret = avc->mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) {
|
||||
if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -929,7 +929,7 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int64_t seq_parameter_set_id = -1;
|
||||
int32_t seq_parameter_set_id = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, seq_parameter_set_id)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -944,7 +944,7 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
|| profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118
|
||||
|| profile_idc == 128
|
||||
) {
|
||||
int64_t chroma_format_idc = -1;
|
||||
int32_t chroma_format_idc = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, chroma_format_idc)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -955,12 +955,12 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
}
|
||||
}
|
||||
|
||||
int64_t bit_depth_luma_minus8 = -1;
|
||||
int32_t bit_depth_luma_minus8 = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, bit_depth_luma_minus8)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t bit_depth_chroma_minus8 = -1;
|
||||
int32_t bit_depth_chroma_minus8 = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, bit_depth_chroma_minus8)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -981,18 +981,18 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
}
|
||||
}
|
||||
|
||||
int64_t log2_max_frame_num_minus4 = -1;
|
||||
int32_t log2_max_frame_num_minus4 = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, log2_max_frame_num_minus4)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t pic_order_cnt_type = -1;
|
||||
int32_t pic_order_cnt_type = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, pic_order_cnt_type)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pic_order_cnt_type == 0) {
|
||||
int64_t log2_max_pic_order_cnt_lsb_minus4 = -1;
|
||||
int32_t log2_max_pic_order_cnt_lsb_minus4 = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, log2_max_pic_order_cnt_lsb_minus4)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1002,17 +1002,17 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int64_t offset_for_non_ref_pic = -1;
|
||||
int32_t offset_for_non_ref_pic = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_non_ref_pic)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t offset_for_top_to_bottom_field = -1;
|
||||
int32_t offset_for_top_to_bottom_field = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_top_to_bottom_field)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t num_ref_frames_in_pic_order_cnt_cycle = -1;
|
||||
int32_t num_ref_frames_in_pic_order_cnt_cycle = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, num_ref_frames_in_pic_order_cnt_cycle)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1023,7 +1023,7 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
}
|
||||
}
|
||||
|
||||
int64_t max_num_ref_frames = -1;
|
||||
int32_t max_num_ref_frames = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, max_num_ref_frames)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1033,12 +1033,12 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int64_t pic_width_in_mbs_minus1 = -1;
|
||||
int32_t pic_width_in_mbs_minus1 = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, pic_width_in_mbs_minus1)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t pic_height_in_map_units_minus1 = -1;
|
||||
int32_t pic_height_in_map_units_minus1 = -1;
|
||||
if ((ret = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ using namespace std;
|
|||
// @see SRS_SYS_TIME_RESOLUTION_MS_TIMES
|
||||
#define SYS_TIME_RESOLUTION_US 300*1000
|
||||
|
||||
int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v)
|
||||
int srs_avc_nalu_read_uev(SrsBitStream* stream, int32_t& v)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -67,7 +67,7 @@ int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v)
|
|||
b = stream->read_bit();
|
||||
}
|
||||
|
||||
if (leadingZeroBits >= 64) {
|
||||
if (leadingZeroBits >= 31) {
|
||||
return ERROR_AVC_NALU_UEV;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class SrsBitStream;
|
|||
#define srs_max(a, b) (((a) < (b))? (b) : (a))
|
||||
|
||||
// read nalu uev.
|
||||
extern int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v);
|
||||
extern int srs_avc_nalu_read_uev(SrsBitStream* stream, int32_t& v);
|
||||
extern int srs_avc_nalu_read_bit(SrsBitStream* stream, int8_t& v);
|
||||
|
||||
// get current system time in ms, use cache to avoid performance problem
|
||||
|
|
|
@ -1243,10 +1243,20 @@ int srs_write_h264_ipb_frame(Context* context,
|
|||
if (!context->h264_sps_pps_sent) {
|
||||
return ERROR_H264_DROP_BEFORE_SPS_PPS;
|
||||
}
|
||||
|
||||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f);
|
||||
|
||||
// for IDR frame, the frame is keyframe.
|
||||
SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame;
|
||||
if (nal_unit_type == SrsAvcNaluTypeIDR) {
|
||||
frame_type = SrsCodecVideoAVCFrameKeyFrame;
|
||||
}
|
||||
|
||||
std::string ibp;
|
||||
int8_t frame_type;
|
||||
if ((ret = context->avc_raw.mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) {
|
||||
if ((ret = context->avc_raw.mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -226,15 +226,10 @@ int SrsRawH264Stream::mux_sequence_header(string sps, string pps, u_int32_t dts,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, u_int32_t dts, u_int32_t pts, string& ibp, int8_t& frame_type)
|
||||
int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
|
||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame
|
||||
u_int8_t nal_unit_type = (char)frame[0] & 0x1f;
|
||||
|
||||
// 4bytes size of nalu:
|
||||
// NALUnitLength
|
||||
// Nbytes of nalu.
|
||||
|
@ -260,12 +255,6 @@ int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, u_int32_t dts, u_
|
|||
// NALUnit
|
||||
stream.write_bytes(frame, nb_frame);
|
||||
|
||||
// send out h264 packet.
|
||||
frame_type = SrsCodecVideoAVCFrameInterFrame;
|
||||
if (nal_unit_type != 1) {
|
||||
frame_type = SrsCodecVideoAVCFrameKeyFrame;
|
||||
}
|
||||
|
||||
ibp = "";
|
||||
ibp.append(packet, nb_packet);
|
||||
|
||||
|
@ -281,7 +270,7 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa
|
|||
// 1bytes, AVCPacketType
|
||||
// 3bytes, CompositionTime, the cts.
|
||||
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
|
||||
int size = video.length() + 5;
|
||||
int size = (int)video.length() + 5;
|
||||
char* data = new char[size];
|
||||
char* p = data;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
* @param ibp output the packet.
|
||||
* @param frame_type output the frame type.
|
||||
*/
|
||||
virtual int mux_ipb_frame(char* frame, int nb_frame, u_int32_t dts, u_int32_t pts, std::string& ibp, int8_t& frame_type);
|
||||
virtual int mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
|
||||
/**
|
||||
* mux the avc video packet to flv video packet.
|
||||
* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame.
|
||||
|
|
Loading…
Reference in a new issue