FFmpeg接收UDP码流

news/2024/5/18 11:52:30 标签: ffmpeg, udp, 网络协议

一、FFmpeg参数初始化:

    //在打开码流前指定各种参数比如:探测时间/超时时间/最大延时等

    //设置缓存大小,1080p可将值调大
    av_dict_set(&options, "buffer_size", "8192000", 0);

    //以tcp方式打开,如果以udp方式打开将tcp替换为udp
    av_dict_set(&options, "rtsp_transport", transport.toUtf8().constData(), 0);

    //设置超时断开连接时间,单位微秒,3000000表示3秒
    av_dict_set(&options, "stimeout", "3000000", 0);

    //设置最大时延,单位微秒,1000000表示1秒
    av_dict_set(&options, "max_delay", "1000000", 0);

    //自动开启线程数
    av_dict_set(&options, "threads", "auto", 0);

    //等待3秒超时
    av_dict_set(&options, "listen_timeout", "3", 0);

二、初始化输入

AVFormatContext* formatCtx = avformat_alloc_context();

//关键函数,提供从udp进行码流读取
//read_udp_packet函数中将opaque转换为UdpReceiver指针(receiver_udp即该指针),从而获得socket信息
//通过调用recvfrom进行udp码流读取
formatCtx->pb = avio_alloc_context(buffer, bufsize,0,receiver_udp, read_udp_packet, NULL, NULL);

int result = avformat_open_input(&formatCtx, 0, ifmt, &options);

三、后续的一系列操作就按照普通解码顺序进行即可。


用UDP读取码流的相关代码:

    //windows平台下初始化套接字
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        return;
    }

    SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if ( sockfd == -1) {
        printf("socket error!!!\n");
        return ;
    }

    int reuse = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse, sizeof(reuse)) < 0) {
        printf("Setting SO_REUSEADDR error");
        closesocket(sockfd);
        return ;
    }

    unsigned int recvBuf = 50*1024*1024;
    int recvBufLen = sizeof(recvBuf);
    auto nErrCode = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,(char*)&recvBuf, recvBufLen);

    sockaddr_in* localaddr = new struct sockaddr_in;
    localaddr->sin_family = AF_INET;
    localaddr->sin_port = htons(MULTICAST_GROUP_PORT);
    localaddr->sin_addr.s_addr = inet_addr(LOCAL_IP.toStdString().c_str())/* htonl(INADDR_ANY)*/;


    struct timeval tv_out;
    tv_out.tv_sec=3000;
    tv_out.tv_usec=0;
    int ret =setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_out, sizeof(tv_out));
    if ( ret == -1 ) {
        printf("setsockopt timeout error!!!\n");
        closesocket(sockfd);
        return ;
    }

    ret = bind(sockfd, (struct sockaddr*)localaddr, sizeof(struct sockaddr));
    if ( ret == -1) {
        printf("bind localaddr error!!!\n");
        auto id = WSAGetLastError();
        closesocket(sockfd);
        return ;
    }

   //是否支持本地回环接收
   int loopBack = 1;
   ret = setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&loopBack, sizeof(loopBack));
   if ( ret == -1) {
       printf("setsockopt broadcaset error!!!\n");
       closesocket(sockfd);
       return ;
   }

    //是否接收广播消息
    struct ip_mreq ipmr = { 0 };
    ipmr.imr_interface.s_addr = inet_addr(LOCAL_IP.toStdString().c_str()) /*(INADDR_ANY)*/;
    ipmr.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP_ADDRESS.toStdString().c_str());
    int len = sizeof(ipmr);
    ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&ipmr, len);
    if ( ret == -1) {
        printf("set error IP_ADD_MEMBERSHIP %d\n", WSAGetLastError());
        closesocket(sockfd);
        return ;
    }


    //关闭套接字,释放资源
    closesocket(sockfd);
    WSACleanup();


http://www.niftyadmin.cn/n/4926351.html

相关文章

数据结构【第4章】——栈与队列

队列是只允许在一端进行插入操作、而在另-端进行删除操作的线性表。 栈 栈与队列&#xff1a;栈是限定仅在表尾进行插入和删除操作的线性表。 我们把允许插入和删除的一端称为栈顶&#xff08;top&#xff09;&#xff0c;另一端称为栈底&#xff08;bottom&#xff09;&…

适用HarmonyOS 3.1版本及以上的应用及服务开发工具 DevEco Studio 3.1.1 Release 安装

文章目录 安装步骤1.下载安装包2.安装成功后&#xff0c;初次运行studio2.1 配置node与ohpm的环境2.2安装sdk2.3等待安装结束 3.创建项目3.1 点击Create Project3.2 选择一个空项目3.3 项目配置3.4 Finish、等待依赖下载完毕3.5 项目创建完成 tip 提示4.配置运行环境4.1 真机运…

VGG16模型详解

VGG16模型详解 0、VGG16介绍 VGG16是一种深度卷积神经网络&#xff0c;由牛津大学的研究团队于2014年开发。 VGG16在2014年的ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 竞赛中取得了显著的成绩。它在图像分类任务中获得了当年的第二名&#xff0c;其准确…

Python 条件语句的高级应用

文章目录 0、背景1、处理多个条件语句1.1 对于all()的一般例子如下: 1.2 对于any()的一般例子如下: 0、背景 原文链接点击这里&#xff0c;本文主要是做收藏。 1、处理多个条件语句 如果我们在代码中需要检查多个条件语句&#xff0c;此时我们可以使用 all() 或any() 函数来…

【力扣】61. 旋转链表 <快慢指针>

【力扣】61. 旋转链表&#xff08;每个节点向右移k个单位&#xff09; 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3] 示例 2&a…

flutter开发实战-TextPainter计算文本内容的宽度

flutter开发实战-TextPainter计算文本内容的宽度 最近开发过程中根据Text文本的大小判断是否需要进行显示跑马灯效果&#xff0c;获取文本的大小&#xff0c;需要TextPainter来获取Size 一、TextPainter TextPainter主要用于实现文本的绘制。TextPainter类可以将TextSpan渲染…

idea双击启动无效,idea卡顿问题

idea双击启动无效&#xff1a;大概率是关机时没有正确关闭idea&#xff0c;再次开机导致无法正常启动idea 1.通过任务管理器杀死idea进程后重启idea 2.需要修改配置 打开 &#xff08;以各自电脑实际为准&#xff09;C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\bin&am…

机器人制作开源方案 | 超市服务机器人

作者&#xff1a;林江斌 岳沛霖 李锦扬 单位&#xff1a;北京理工大学 机械与车辆学院 指导老师&#xff1a;李忠新 朱杰 一、作品简介 1.设计背景 当前社会疫情防控已经成为常态化&#xff0c;超市是人员流动相对密集的公共场所&#xff0c;超市防疫也是社会防疫工作中重要…