rtmp推流异常分析

文章讲述了在向SRS媒体服务推送RTMP流时遇到的问题,涉及SRS日志中的错误代码,发现是由于AVCDecoderConfigurationRecord中的SPS/PPS解析异常。推流端首帧视频数据长度不符合SRS代码预期,导致错误。
摘要由CSDN通过智能技术生成

问题描述

向srs媒体服务上推送rtmp流,推送失败

分析过程

srs日志分析

从日志中看到发生错误时层次调用关系

[2023-09-05 11:10:29.933][Error][13594][9w5og10q][11] serve error code=3001 : service cycle : rtmp: stream service : rtmp: receive thread : handle publish message : rtmp: consume message : rtmp: consume video : meta update video : demux SPS/PPS : avc decode sequence header

去代码中搜索"avc decode sequence header"相关信息,发现是解析sps/pps信息异常

// src/kernel/srs_kernel_codec.cpp
srs_error_t SrsFormat::avc_demux_sps_pps(SrsBuffer* stream)
{
    // AVCDecoderConfigurationRecord
    // 5.2.4.1.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16
    int avc_extra_size = stream->size() - stream->pos();
    if (avc_extra_size > 0) {
        char *copy_stream_from = stream->data() + stream->pos();
        vcodec->avc_extra_data = std::vector<char>(copy_stream_from, copy_stream_from + avc_extra_size);
    }

    if (!stream->require(6)) {
        return srs_error_new(ERROR_HLS_DECODE_ERROR, "avc decode sequence header");
    }

    ......
}

stream对应的buffer中不够6个字节???

抓包分析

推流端给服务端发送完publish之后,服务端回复的onStatus,以及客户端给服务端发送的setDataFrame、onMetaData都没有被解析成rtmp,只能根据rtmp协议标准分析onMetaData(及ECMA Array)之后的数据,srs日志中也表示获取到了meta data                        

[2023-09-05 11:10:29.927][Trace][13594][9w5og10q] got metadata, width=1280, height=720, vcodec=7, acodec=10

再结合srs的日志,猜测是sps/pps解析引起的

onMetaData的"End Of Object Marker"对应着0x00 0x00 0x09序列,其后对应着其他的rtmp包

rtmp的header中各字段含义表示为

RTMP字段
字段分类字段含义位宽描述
Headerformat2bits

0表示header长度为11字节

1表示header长度为7字节

2表示header长度为3字节

3表示header长度为0字节

(不含本字节)

ChunkStreamID6bits
TimeStamp3Bytes
BodySize3Bytes
TypeId1Byte

0x08对应语音数据

0x09对应视频数据

StreamId4Bytes

Body

(需要根据header中TypeId区分,这里只描述audio/video)

Control1Byte视频数据       Type: 4bits, 1表示Key Frame; 2表示inter-frame     
Format: 4bits, 7表示H264
语音数据

Format: 4bits, 10表示HE-AAc

SampleRate: 2bits, 3表示44kHz

SampleSize: 1bit, 1表示16bits

Channels: 1bit, 1表示Stereo

DataBodySize - 1

抓包和rtmp协议规范对着看吧,第一个视频帧长度为5并且有效数据是00 00 00 00,代码中要求长度是6,所以对上号了

结论

推流端首帧视频数据长度为5,真实数据为00 00 00 00, 代码中要求是6,所以srs代码中校验不通过,报错。

猜测是客户端首帧编码异常,或者发送的太早了,数据还没编码好就开始发送了......

参考

setDataFrame、onMetaData协议格式参考手撕Rtmp协议细节(8)——publish推流_视界音你而不同的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值