Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[技术咨询] ZLM有支持Slice解码吗? #3551

Closed
iChenwin opened this issue May 17, 2024 · 6 comments
Closed

[技术咨询] ZLM有支持Slice解码吗? #3551

iChenwin opened this issue May 17, 2024 · 6 comments

Comments

@iChenwin
Copy link

咨询的功能模块

  • mk_frame.cpp

咨询的具体内容和问题

  • 使用ZLM拉取多Slice编码的H.264流,然后喂给ffmpeg软解播放,出现花屏,分析发现mk_frame_get_data吐出来的数据没有将多个Slice合并为一帧,请问下目前有支持将多个Slice合并成一个frame的实现吗?
[2024-05-17 15:58:33.533]mk_frame_get_data, frameSize:19, pts:45555929
[2024-05-17 15:58:33.533]mk_frame_get_data, frameSize:9, pts:45555929
[2024-05-17 15:58:33.533]mk_frame_get_data, frameSize:93802, pts:45555929
[2024-05-17 15:58:33.534]mk_frame_get_data, frameSize:98741, pts:45555929
[2024-05-17 15:58:33.534]mk_frame_get_data, frameSize:98735, pts:45555929
[2024-05-17 15:58:33.534]mk_frame_get_data, frameSize:93640, pts:45555929
[2024-05-17 15:58:33.534]mk_frame_get_data, frameSize:90481, pts:45555929
[2024-05-17 15:58:33.535]mk_frame_get_data, frameSize:98460, pts:45555929
[2024-05-17 15:58:33.535]mk_frame_get_data, frameSize:102508, pts:45555929
[2024-05-17 15:58:33.535]mk_frame_get_data, frameSize:112510, pts:45555929
[2024-05-17 15:58:33.535]mk_frame_get_data, frameSize:20050, pts:45555929
[2024-05-17 15:58:33.535]mk_frame_get_data, frameSize:7725, pts:45555951
[2024-05-17 15:58:33.536]mk_frame_get_data, frameSize:9355, pts:45555966
[2024-05-17 15:58:33.538]mk_frame_get_data, frameSize:9850, pts:45555966
[2024-05-17 15:58:33.538]mk_frame_get_data, frameSize:10725, pts:45555967
[2024-05-17 15:58:33.539]mk_frame_get_data, frameSize:10840, pts:45556015
@xiongguangjie
Copy link
Member

这个不支持,需要播放器自己合并,这个在流媒体服务器里面有类似的代码参考这个
17160221048399

@xia-chu
Copy link
Member

xia-chu commented May 20, 2024

  • 使用ZLM拉取多Slice编码的H.264流,然后喂给ffmpeg软解播放,出现花屏,分析发现mk_frame_get_data吐出来的数据没有将多个Slice合并为一帧,请问下目前有支持将多个Slice合并成一个frame的实现吗?

test_player.cpp支持的 外部需要自己把时间戳相同的帧merge一下再解码。

不过新版的ffmpeg(6.0+) 好像已经不需要merge了 它内部会自己merge

zlmediakit的Transcode.cpp中的FFmpegDecoder对象会对帧进行merge

@iChenwin
Copy link
Author

  • 使用ZLM拉取多Slice编码的H.264流,然后喂给ffmpeg软解播放,出现花屏,分析发现mk_frame_get_data吐出来的数据没有将多个Slice合并为一帧,请问下目前有支持将多个Slice合并成一个frame的实现吗?

test_player.cpp支持的 外部需要自己把时间戳相同的帧merge一下再解码。

不过新版的ffmpeg(6.0+) 好像已经不需要merge了 它内部会自己merge

zlmediakit的Transcode.cpp中的FFmpegDecoder对象会对帧进行merge

ts吐帧,我看是通过Decoder.cpp的onDecode把帧送上去的,在这个cpp里也看到有个FrameMerger,是不是稍作修改也能在_merger.inputFrame那里把多个Slice合成一个完整帧?

@iChenwin iChenwin reopened this May 22, 2024
@xiongguangjie
Copy link
Member

  • 使用ZLM拉取多Slice编码的H.264流,然后喂给ffmpeg软解播放,出现花屏,分析发现mk_frame_get_data吐出来的数据没有将多个Slice合并为一帧,请问下目前有支持将多个Slice合并成一个frame的实现吗?

test_player.cpp支持的 外部需要自己把时间戳相同的帧merge一下再解码。
不过新版的ffmpeg(6.0+) 好像已经不需要merge了 它内部会自己merge
zlmediakit的Transcode.cpp中的FFmpegDecoder对象会对帧进行merge

ts吐帧,我看是通过Decoder.cpp的onDecode把帧送上去的,在这个cpp里也看到有个FrameMerger,是不是稍作修改也能在_merger.inputFrame那里把多个Slice合成一个完整帧?

是的,你可以这么做

@xia-chu xia-chu closed this as completed May 23, 2024
@iChenwin
Copy link
Author

iChenwin commented May 27, 2024

针对我手上的H.264 ts流,刚试验了一种改法,成功了。在H264.cpp里的splitH264函数中,不去把I/P Slice分割开,一整个抛给上层播放器,画面就正常了。希望这能对其他人有帮助。
@xia-chu @xiongguangjie 二位大佬,这样改的普适性大吗?同一个PES里的所有I Slice不去拆分它,把它一整个抛上去,只拆分SPS、PPS。
代码新增了一个SPS、PPS判断:

        bool is_config_frame = ((*((char *)start) & 0x1f) == 0x07  || (*((char *)start) & 0x1f) == 0x08);

        if (true == is_config_frame)
        {

修改后的代码。

void splitH264(
    const char *ptr, size_t len, size_t prefix, const std::function<void(const char *, size_t, size_t)> &cb) {
    auto start = ptr + prefix;
    auto end = ptr + len;
    size_t next_prefix;
    while (true) {
        auto next_start = memfind(start, end - start, "\x00\x00\x01", 3);
        bool is_config_frame = ((*((char *)start) & 0x1f) == 0x07  || (*((char *)start) & 0x1f) == 0x08);
       //只有参数集帧,才进行拆分
        if (true == is_config_frame)
        {
            if (next_start) {
                //找到下一帧
                if (*(next_start - 1) == 0x00) {
                    //这个是00 00 00 01开头
                    next_start -= 1;
                    next_prefix = 4;
                } else {
                    //这个是00 00 01开头
                    next_prefix = 3;
                }
                //记得加上本帧prefix长度
                cb(start - prefix, next_start - start + prefix, prefix);
                //搜索下一帧末尾的起始位置
                start = next_start + next_prefix;
                //记录下一帧的prefix长度
                prefix = next_prefix;
                continue;
            }
        }
        //未找到下一帧,这是最后一帧
        cb(start - prefix, end - start + prefix, prefix);
        break;
    }
}

@xia-chu
Copy link
Member

xia-chu commented May 27, 2024

@iChenwin
多个slice在一起 会影响rtp打包不?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants