zoukankan      html  css  js  c++  java
  • av_interleaved_write_frame 网络不好的情况下返回较慢

    用libvlc做直播推流引擎
    在网络较差的情况下,需要关闭直播,并且重新开播。
    这个过程中,推流引擎重启,需要的是快速响应。
    实际上测试结果发现,经常会发生引擎关闭接口卡住。
    后来跟踪代码,定位到s_rtmp_send_thread() 中
    其中一句:
    ret = av_interleaved_write_frame(formatContext, pkt);
    这个方法在网络较好的情况下,一般是几个毫秒就返回发送成功。
    然后在网络较差的情况下,会一直卡在这里,没有返回。。。

    跟踪ffmpeg代码,这个方法的实现在mux.c
    libavformat/mux.c
    av_interleaved_write_frame()
    write_packet() 真正写数据
    ret = s->oformat->write_packet(s, pkt);
    write_packet 这里就是一个定义在avformat.h中的指针,指向flv_write_packet()

    经一步跟踪代码,发现关于网络读写的超时控制,定义在url.h中

    typedef struct URLContext {
    ......
    int64_t rw_timeout; /**< maximum time to wait for (network) read/write 
    ......
    } URLContext;

    于是在初始化的地方,设置这个参数:

    libavformat/avio.c --->
    url_alloc_for_protocol() return之前添加如下语句

    // 网络读写超时 控制在 800ms

    if (0 == uc->rw_timeout || uc->rw_timeout > 800000)
            uc->rw_timeout = 800000;

    回到项目中,在av_interleaved_write_frame两端输出时间,发现现在这个接口在网络不好的情况下,基本控制在1s以内。然后并不是精确的时间控制。貌似ffmpeg本身都不能严格控制到毫秒级别。

    为了确保这个返回一定得到响应,同时在libavformat/mux.c
    av_interleaved_write_frame()中修改下面的代码:

    for(;;) 

    这个没有控制的for循环,改为

    int mOutTimes = 128;
    int nn;
    for(nn=0;nn<mOutTimes;nn++)

    这里的128是个经验值。

  • 相关阅读:
    VScode 关闭回车后自动格式化代码
    『转载』专利申请
    『转载』 免费公用DNS服务及三大运营商DNS大全 含IPV4和IPV6
    正则表达式和元字符
    随机背景图
    秒表
    数组相关的函数
    对象的结构语法
    数组的结构语法
    展开合并运算符
  • 原文地址:https://www.cnblogs.com/zzugyl/p/5417478.html
Copyright © 2011-2022 走看看