mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	RTC: Support dropping h.264 SEI from NALUs. v5.0.213 v6.0.125 (#4057)
try to fix #4052. --------- Co-authored-by: winlin <winlinvip@gmail.com>
This commit is contained in:
		
							parent
							
								
									282d94d7bb
								
							
						
					
					
						commit
						1656391c67
					
				
					 12 changed files with 141 additions and 66 deletions
				
			
		| 
						 | 
				
			
			@ -504,63 +504,23 @@ SrsSample::SrsSample()
 | 
			
		|||
{
 | 
			
		||||
    size = 0;
 | 
			
		||||
    bytes = NULL;
 | 
			
		||||
    bframe = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsSample::SrsSample(char* b, int s)
 | 
			
		||||
{
 | 
			
		||||
    size = s;
 | 
			
		||||
    bytes = b;
 | 
			
		||||
    bframe = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsSample::~SrsSample()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
srs_error_t SrsSample::parse_bframe()
 | 
			
		||||
{
 | 
			
		||||
    srs_error_t err = srs_success;
 | 
			
		||||
 | 
			
		||||
    uint8_t header = bytes[0];
 | 
			
		||||
    SrsAvcNaluType nal_type = (SrsAvcNaluType)(header & kNalTypeMask);
 | 
			
		||||
 | 
			
		||||
    if (nal_type != SrsAvcNaluTypeNonIDR && nal_type != SrsAvcNaluTypeDataPartitionA && nal_type != SrsAvcNaluTypeIDR) {
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SrsBuffer* stream = new SrsBuffer(bytes, size);
 | 
			
		||||
    SrsAutoFree(SrsBuffer, stream);
 | 
			
		||||
 | 
			
		||||
    // Skip nalu header.
 | 
			
		||||
    stream->skip(1);
 | 
			
		||||
 | 
			
		||||
    SrsBitBuffer bitstream(stream);
 | 
			
		||||
    int32_t first_mb_in_slice = 0;
 | 
			
		||||
    if ((err = srs_avc_nalu_read_uev(&bitstream, first_mb_in_slice)) != srs_success) {
 | 
			
		||||
        return srs_error_wrap(err, "nalu read uev");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int32_t slice_type_v = 0;
 | 
			
		||||
    if ((err = srs_avc_nalu_read_uev(&bitstream, slice_type_v)) != srs_success) {
 | 
			
		||||
        return srs_error_wrap(err, "nalu read uev");
 | 
			
		||||
    }
 | 
			
		||||
    SrsAvcSliceType slice_type = (SrsAvcSliceType)slice_type_v;
 | 
			
		||||
 | 
			
		||||
    if (slice_type == SrsAvcSliceTypeB || slice_type == SrsAvcSliceTypeB1) {
 | 
			
		||||
        bframe = true;
 | 
			
		||||
        srs_verbose("nal_type=%d, slice type=%d", nal_type, slice_type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsSample* SrsSample::copy()
 | 
			
		||||
{
 | 
			
		||||
    SrsSample* p = new SrsSample();
 | 
			
		||||
    p->bytes = bytes;
 | 
			
		||||
    p->size = size;
 | 
			
		||||
    p->bframe = bframe;
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -655,7 +615,6 @@ srs_error_t SrsFrame::add_sample(char* bytes, int size)
 | 
			
		|||
    SrsSample* sample = &samples[nb_samples++];
 | 
			
		||||
    sample->bytes = bytes;
 | 
			
		||||
    sample->size = size;
 | 
			
		||||
    sample->bframe = false;
 | 
			
		||||
    
 | 
			
		||||
    return err;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -739,6 +698,64 @@ SrsVideoCodecConfig* SrsVideoFrame::vcodec()
 | 
			
		|||
    return (SrsVideoCodecConfig*)codec;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
srs_error_t SrsVideoFrame::parse_avc_nalu_type(const SrsSample* sample, SrsAvcNaluType& avc_nalu_type)
 | 
			
		||||
{
 | 
			
		||||
    srs_error_t err = srs_success;
 | 
			
		||||
 | 
			
		||||
    if (sample == NULL || sample->size < 1) {
 | 
			
		||||
        return srs_error_new(ERROR_AVC_NALU_EMPTY, "empty nalu");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    uint8_t header = sample->bytes[0];
 | 
			
		||||
    avc_nalu_type = (SrsAvcNaluType)(header & kNalTypeMask);
 | 
			
		||||
    
 | 
			
		||||
    return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
srs_error_t SrsVideoFrame::parse_avc_b_frame(const SrsSample* sample, bool& is_b_frame)
 | 
			
		||||
{
 | 
			
		||||
    srs_error_t err = srs_success;
 | 
			
		||||
 | 
			
		||||
    if (sample == NULL || sample->size < 1) {
 | 
			
		||||
        return srs_error_new(ERROR_AVC_NALU_EMPTY, "empty nalu");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SrsAvcNaluType nalu_type;
 | 
			
		||||
    if ((err = parse_avc_nalu_type(sample, nalu_type)) != srs_success) {
 | 
			
		||||
        return srs_error_wrap(err, "parse avc nalu type error");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (nalu_type != SrsAvcNaluTypeNonIDR && nalu_type != SrsAvcNaluTypeDataPartitionA && nalu_type != SrsAvcNaluTypeIDR) {
 | 
			
		||||
        is_b_frame = false;
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SrsBuffer* stream = new SrsBuffer(sample->bytes, sample->size);
 | 
			
		||||
    SrsAutoFree(SrsBuffer, stream);
 | 
			
		||||
 | 
			
		||||
    // Skip nalu header.
 | 
			
		||||
    stream->skip(1);
 | 
			
		||||
 | 
			
		||||
    SrsBitBuffer bitstream(stream);
 | 
			
		||||
    int32_t first_mb_in_slice = 0;
 | 
			
		||||
    if ((err = srs_avc_nalu_read_uev(&bitstream, first_mb_in_slice)) != srs_success) {
 | 
			
		||||
        return srs_error_wrap(err, "nalu read uev");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int32_t slice_type_v = 0;
 | 
			
		||||
    if ((err = srs_avc_nalu_read_uev(&bitstream, slice_type_v)) != srs_success) {
 | 
			
		||||
        return srs_error_wrap(err, "nalu read uev");
 | 
			
		||||
    }
 | 
			
		||||
    SrsAvcSliceType slice_type = (SrsAvcSliceType)slice_type_v;
 | 
			
		||||
 | 
			
		||||
    is_b_frame = slice_type == SrsAvcSliceTypeB || slice_type == SrsAvcSliceTypeB1;
 | 
			
		||||
    if (is_b_frame) {
 | 
			
		||||
        srs_verbose("nalu_type=%d, slice type=%d", nalu_type, slice_type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsFormat::SrsFormat()
 | 
			
		||||
{
 | 
			
		||||
    acodec = NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1120,7 +1120,7 @@ std::string srs_hevc_level2str(SrsHevcLevel level);
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * A sample is the unit of frame.
 | 
			
		||||
 * It's a NALU for H.264.
 | 
			
		||||
 * It's a NALU for H.264, H.265.
 | 
			
		||||
 * It's the whole AAC raw data for AAC.
 | 
			
		||||
 * @remark Neither SPS/PPS or ASC is sample unit, it's codec sequence header.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1131,15 +1131,11 @@ public:
 | 
			
		|||
    int size;
 | 
			
		||||
    // The ptr of unit, user must free it.
 | 
			
		||||
    char* bytes;
 | 
			
		||||
    // Whether is B frame.
 | 
			
		||||
    bool bframe;
 | 
			
		||||
public:
 | 
			
		||||
    SrsSample();
 | 
			
		||||
    SrsSample(char* b, int s);
 | 
			
		||||
    ~SrsSample();
 | 
			
		||||
public:
 | 
			
		||||
    // If we need to know whether sample is bframe, we have to parse the NALU payload.
 | 
			
		||||
    srs_error_t parse_bframe();
 | 
			
		||||
    // Copy sample, share the bytes pointer.
 | 
			
		||||
    SrsSample* copy();
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1322,6 +1318,9 @@ public:
 | 
			
		|||
    virtual srs_error_t add_sample(char* bytes, int size);
 | 
			
		||||
public:
 | 
			
		||||
    virtual SrsVideoCodecConfig* vcodec();
 | 
			
		||||
public:
 | 
			
		||||
    static srs_error_t parse_avc_nalu_type(const SrsSample* sample, SrsAvcNaluType& avc_nalu_type);
 | 
			
		||||
    static srs_error_t parse_avc_b_frame(const SrsSample* sample, bool& is_b_frame);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -276,7 +276,8 @@
 | 
			
		|||
    XX(ERROR_HEVC_DISABLED                 , 3098, "HevcDisabled", "HEVC is disabled") \
 | 
			
		||||
    XX(ERROR_HEVC_DECODE_ERROR             , 3099, "HevcDecode", "HEVC decode av stream failed")  \
 | 
			
		||||
    XX(ERROR_MP4_HVCC_CHANGE               , 3100, "Mp4HvcCChange", "MP4 does not support video HvcC change") \
 | 
			
		||||
    XX(ERROR_HEVC_API_NO_PREFIXED          , 3101, "HevcAnnexbPrefix", "No annexb prefix for HEVC decoder")
 | 
			
		||||
    XX(ERROR_HEVC_API_NO_PREFIXED          , 3101, "HevcAnnexbPrefix", "No annexb prefix for HEVC decoder") \
 | 
			
		||||
    XX(ERROR_AVC_NALU_EMPTY                , 3102, "AvcNaluEmpty", "AVC NALU is empty")
 | 
			
		||||
 | 
			
		||||
/**************************************************/
 | 
			
		||||
/* HTTP/StreamConverter protocol error. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue