美文网首页FFmpeg
ijkplayer在rtsp协议下使用经验

ijkplayer在rtsp协议下使用经验

作者: 睡后3k | 来源:发表于2016-12-06 23:32 被阅读7185次

    折腾ijkplayer也有好一段时间,我司使用rtsp输出设备的视频流,要求实时性1s以下,如果使用默认配置必然是不够的;另外ijkplayer本身的使用环境也不是特别为这个实时输出而设;总免不了自己打磨一下。

    编译配置

    • 修改module-lite.sh
      这里不直接使用module-default.sh这个配置,太大,而我们业务只需要rtmprtsp
      在配置中添加
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=tcp"
    

    rtsp over tcp 或 rtsp over udp

    我们两个设备一个支持tcp一个支持udp, 只能动态配置, ffmpeg默认是rtsp over udp,而使用rtsp over tcp, 在read_thread中添加至

    av_dict_set(&ffp->format_opts, "rtsp_transport", "udp", 0);
    

    当然不能写死,可以在ff_ffplay_options.h添加
    thx@大牙
    ffmpeg的配置只需要在
    [options setFormatOptionValue:@"tcp" forKey:@"rtsp_transport"];
    不用自行扩展

    关闭队列满载或者空时等待

    在满载或者空的停下来等待10ms本来是一个很好的设计,但是对于实时要求高的来说这个是致命的
    所以得把wait 10ms这段代码注释

    /* wait 10 ms */
    SDL_LockMutex(wait_mutex);
    //SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
    SDL_UnlockMutex(wait_mutex);
    continue;
    

    关闭队列满载或者空时暂停/启动切换

    另外,还得吧ffp_toggle_buffering(ffp, 1) 的地方干掉, 不干掉的话,会发现ffp_toggle_buffering(ffp, 0) 执行时,我们没有动态码率的需求,VideoToolBox会重新创建, 没有必要浪费这性能(何况我们推流的SDP报文sps还必须重启服务器才会替换

    static int packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue *q, AVPacket *pkt, int *serial, int *finished)
    {
      ......
           //ffp_toggle_buffering(ffp, 1);
      .......
    }
    

    调整rtsp本身配置

    在原来的代码里面我们会看到这么一句

    if (av_stristart(is->filename, "rtmp", NULL) ||
      av_stristart(is->filename, "rtsp", NULL)) {
            // There is total different meaning for 'timeout' option in rtmp
            av_log(ffp, AV_LOG_WARNING, "remove 'timeout' option for rtmp.\n");
            av_dict_set(&ffp->format_opts, "timeout", NULL, 0);
        }
    

    因为rtsp配置参数是另外几个字段控制的,我这里配置rtsp建立会话的超时和rtp传输超时

    av_dict_set(&ffp->format_opts, "initial_timeout", "5000000", 0);
    av_dict_set(&ffp->format_opts, "stimeout", "500000", 0); //us
    

    另外还有两个AVFormatContext 中对我们业务来说非常重要的字段

    ic->max_delay = 5000;
    ic->probesize = 200;
    

    max_delay 默认配置5000000ns(5s), 延时会慢慢累积,跑个几十分钟会发现延时会增大,但是v-cache依然只有几个包的情况
    probesize 是影响av_find_input_format取多少个样本计算fps, tbs, tba之类的参数。我们的需求就是要快,我们的头一帧是sps和pps,所以基本不会影响后续帧的传输;通过调试大法得到200左右的值,第一帧出来只需要500ms左右。

    IJKSDLView 输出到自定义OpenGL上

    IJKSDLView对我们来说基本是个负担,修改render.c太麻烦, 直接在
    - (void)display: (SDL_VoutOverlay *) overlay 方法中把CVImageBufferRef通过代理送出去,简单省事
    Android可以直接替换Surface,iOS没有这种好事这里又打了自己的脸

    相关文章

      网友评论

        本文标题:ijkplayer在rtsp协议下使用经验

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