美文网首页
关于SRS中sps,pps解析的一个bug

关于SRS中sps,pps解析的一个bug

作者: hijiang | 来源:发表于2019-06-29 15:52 被阅读0次

    最近在修改srs,今天发现有个明显的bug,虽然不会造成大问题,不知道为何winlin没有修复,可能是暂时没用到吧。

    int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
    

    用到了指数哥伦布编码解码算法

    • ue(v):使用无符号指数哥伦布解码;
    • se(v):使用有符号指数哥伦布解码;

    根据文档(H.264-AVC-ISO_IEC_14496-10-2012.pdf)第42页:


    sps数据语法

    这里对offset_for_non_ref_pic,offset_for_top_to_bottom_field, offset_for_ref_frame的解析需要采用se方式,可是代码中使用了ue方式解析

           //这里写错了,应该是se
            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;
            }
            
            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;
            }
            
            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;
            }
            if (num_ref_frames_in_pic_order_cnt_cycle < 0) {
                ret = ERROR_HLS_DECODE_ERROR;
                srs_error("sps the num_ref_frames_in_pic_order_cnt_cycle invalid. ret=%d", ret);
                return ret;
            }
            for (int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
                int32_t offset_for_ref_frame_i = -1;
                if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_ref_frame_i)) != ERROR_SUCCESS) {
                    return ret;
                }
            }
    

    根据文档H.264-AVC-ISO_IEC_14496-10-2012.pdf第208页的说明:
    Depending on the descriptor, the value of a syntax element is derived as follows:
    – If the syntax element is coded as ue(v), the value of the syntax element is equal to codeNum.
    – Otherwise, if the syntax element is coded as se(v), the value of the syntax element is derived by invoking the
    mapping process for signed Exp-Golomb codes as specified in clause 9.1.1 with codeNum as the input.
    – Otherwise, if the syntax element is coded as me(v), the value of the syntax element is derived by invoking the
    mapping process for coded block pattern as specified in clause 9.1.2 with codeNum as the input.
    对于se编码的数据,需要得到codeNum然后再用codeNum执行下一步计算:


    se计算方法

    于是修改了下se读取方法:

    func (this *SrsBitStream) ReadSEV() (int32, error) {
        codeNum, err := this.ReadUEV()
        if err != nil {
            return 0, err
        }
        // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 229
        //(−1)k+1 Ceil( k÷2 )
        var v int32 = 0
        v = int32(math.Ceil(float64(codeNum)/2))
        if codeNum%2 == 0 {
            v = (-1)*v
        }
        return v, nil
    }
    

    相关文章

      网友评论

          本文标题:关于SRS中sps,pps解析的一个bug

          本文链接:https://www.haomeiwen.com/subject/scypcctx.html