实际工作中,我们经常会向其他同事咨询一些技术问题。但是,他给出的答案一定是正确的吗?
近期项目组遇到这么个问题,Android平台上软件解码RTSP实时视频流CPU占用率较高,打算切换到硬件解码。但是在调用硬件解码接口的时候返回失败,原因是视频流的分辨率信息未知,结果又自动切换回了软解。
那么,基于RTSP传输的视频流,一般可以从哪里获取分辨率信息呢?
- RTSP报文中的SDP,一般会有SPS、PPS信息,这里可以拿到(具体术语不展开介绍,感兴趣自行搜索)。
- RTP扩展头:RTP协议允许对头部进行扩展,当然扩展信息你爱填啥就填啥,并不限于分辨率信息,相当于私有信息。
- 码流中的SPS信息。实际实现中,很多公司都会把SPS、PPS信息穿插在码流中,一般的做法是SPS、PPS紧挨着I帧,并且位于I帧的前面(位于前面的好处是解码库拿到该信息,就可以解码紧挨着的I帧,否则紧挨着的I帧就要被缓存起来或者丢掉)。有些实现是每个I帧前面都有SPS、PPS,有些实现是仅当视频信息变化时才插入SPS、PPS。
询问解码库同事,说分辨率信息是从RTP扩展头部获取的。我们设备端没有扩展RTP头,所以取不到分辨率信息,导致硬解失败。这个答复听起来挺有道理的,但是仔细想想经不起推敲啊:
- 硬解拿不到分辨率信息,软解就拿到了?如果软解也拿不到,为何又能解码?
- 公司的解码库经常用来对接第三方设备,别人的设备不一定填充RTP扩展头,即使填充了,格式也未必和我司的定义一致。难道我们的解码库解不了第三方的视频流?这和事实不符啊。
- 之前调试的设备,从抓包信息看,也并未填充RTP扩展头,但是却可以用硬解。
带着这些疑问再次询问解码库同事,终于得到了合理的答复:
- 如果存在RTP扩展头,他们优先从扩展头获取分辨率信息
- 如果没有扩展头,他们就从码流中的SPS获取分辨率信息
注:这里有个遗憾,我们居然没有使用RTSP报文中的SDP。
问题依然存在,为何硬解获取不到分辨率,软解能获取到呢?
抓包看下吧。原来第一个I帧前无SPS、PPS信息,而后面每个I帧前面都有SPS、PPS。排查设备端代码发现,RTP封装库中,在发第一个I帧的时候,把SPS、PPS信息丢了!!!
通过这次事件可以看到,别人提供给你的信息不一定是准确的,甚至有可能是错误的。他不一定是有意给你提供不准确的信息,有可能仅仅是因为他对问题理解的局限性,对相关知识的熟悉程度。为了避免被不准确的信息所害,我们一定要保持独立思考的习惯,多问几个为什么。