小弟在用 ffmpeg 做一个直播流的播放器,发现当直播流中 265 切成 264 ,播放器会卡死,查了下是 ffmpeg 的 265 封装器没法直接解析 264 的封装头部,于是找到解析报错的地方是在 ff_h2645_packet_split 里的 hevc_parse_nal_header 。 本以为把这个 ret 为负的报错抛上去就能解决了。 结果改完后,发现个别手机的正常 265 直播流也会 ret<0 ,这下不知道该怎么区分是编码格式切换引起还是个简单的 warning 了。 有大神能给点思路吗?
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int is_nalff, int nal_length_size, enum AVCodecID codec_id)
{
......
if (codec_id == AV_CODEC_ID_HEVC)
ret = hevc_parse_nal_header(nal, logctx);
else
ret = h264_parse_nal_header(nal, logctx);
if (ret <= 0 || nal->size <= 0) {
if (ret < 0) {
av_log(logctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n",
nal->type);
}
pkt->nb_nals--;
}
......
}
1
iamzuoxinyu 2022-05-26 12:30:36 +08:00
h265 又不向下兼容 h264 吧。切编码的时候不是能拿到 sps 还是 pps 来着?犯不着改 ffmpeg 代码吧。
|
2
JusticeLanding OP @iamzuoxinyu 流是 ffmpeg 收的,ffmpeg 里面都还没把一段段 ts 拼凑成一帧递给上层,还没到 sps pps 的阶段。上面这个函数就是在尝试从 buffer 里面组装出一帧。sps pps 也是帧的一种吧,数据还在 buffer 里
|
3
iamzuoxinyu 2022-05-26 16:24:39 +08:00
@JusticeLanding 我应该是理解错了。是说 ffmpeg 拉流时源切换了编码,然后 ffmpeg 报 warning ?是直接用的 ffmpeg 命令行还是用了 libav 的库?不太清楚你的流程。
|
4
Huelse 2022-05-26 16:47:06 +08:00
思路不对吧?应该分开处理的
之前做网页播放器用了 hls.js ,m3u8 切换起来还是很方便的 |
5
toss156 2022-05-26 16:56:56 +08:00
一般来说 h264 和 h265 ,拉的不同的流,切换应该重置解码器,重新开始解析。 还是说你想要实现无缝切换?
|
6
marchel3255 2022-05-26 16:59:36 +08:00
没办法无缝的吧, 切流需要重制编码器的
|
7
iamzuoxinyu 2022-05-26 17:01:27 +08:00
@marchel3255 无缝切换倒也可以,就是缓冲几帧嘛,牺牲一下 latency 。
|
9
Latin 2022-05-26 18:22:37 +08:00
ffprobe 先看下?
|
10
JusticeLanding OP @iamzuoxinyu
@Huelse 用的 libav ,我这直播是只有一个 ts 链接,ffmpeg 只打开了一次。m3u8 里有多个 ts 链接,重新 open 是可以无缝切换的。 @toss156 @marchel3255 @iamzuoxinyu @ysc3839 没有想要无缝切换,想要识别到编码切换了,上报错误让播放器停止播放,让用户重新点播。 |
11
iamzuoxinyu 2022-05-26 19:06:44 +08:00
@JusticeLanding 是怎么推流的?切换编码时不会产生 EOF 么?
|
12
haah 2022-05-26 19:59:15 +08:00
两种编码完全不一样,好奇你咋切?
|