
软件开发
文章平均质量分 61
音视频牛哥
牛哥@大牛直播SDK,致力于跨平台的实时RTMP推流、转发、RTMP/RTSP直播播放、GB28181设备接入...
展开
-
结合Linux平台RTSP|RTMP播放器demo谈谈std::remove_if
好多开发者可能会疑惑,你一个搞音视频开发的,怎么做起了C++基础普及的事情?搞音视频底层开发的,大多需要有相对好的C C++基础,这里提到的std::remove_if,也是因为大牛直播SDK的demo代码里面有用到。有些对接的开发者容易疑惑,做个基础的扫盲。它的主要功能是根据用户提供的条件,将容器中满足该条件的元素移除。通过这种方式,你可以方便地根据自定义条件从容器中移除元素,并且代码简洁高效。原创 2025-01-21 17:57:40 · 258 阅读 · 0 评论 -
音视频基础扫盲之认识PCM(Pulse Code Modulation,脉冲编码调制)
例如,对于 5.1 声道、采样率为 48000Hz、位深度为 24 位的音频,每个样本占用 3 个字节(24 位转换为 3 个字节)。例如,对于同样采样率为 44100Hz、位深度为 16 位、时长为 5 秒的立体声音频,总样本数量为 220500×2(左右声道各有相同数量的样本)。数据存储时,先存储左声道第一个样本的 2 个字节,再存储右声道第一个样本的 2 个字节,然后是左声道第二个样本、右声道第二个样本,以此类推。按照特定的声道顺序依次存储每个声道的样本,同样可以采用交错或非交错的方式。原创 2024-11-25 16:54:58 · 1142 阅读 · 0 评论 -
音视频基础扫盲之I帧和IDR帧区别
I帧是一种独立的帧,它不依赖于其他帧进行编码。I 帧包含了完整的图像信息,可以单独解码成一幅完整的图像。作用:作为视频序列中的关键参考帧,I 帧为视频的解码提供了初始的图像数据。在视频播放过程中,如果出现丢包或错误,播放器可以利用 I 帧进行恢复,重新开始解码过程。例如,在网络不稳定的情况下,当部分帧丢失时,播放器可以等待下一个 I 帧到达后继续解码播放,从而减少播放中断的影响。原创 2024-11-25 16:36:21 · 879 阅读 · 0 评论 -
计算机视觉之OpenCV vs YOLO
OpenCV 和 YOLO 在计算机视觉领域各有特点和优势。OpenCV 是一个功能强大的计算机视觉库,提供了广泛的算法和工具;而 YOLO 是一种高效的目标检测算法,适用于特定的应用场景。在实际应用中,可以根据具体需求选择合适的工具和算法。原创 2024-10-10 00:03:54 · 3814 阅读 · 0 评论 -
计算机视觉之YOLO算法基本原理和应用场景
YOLO 作为一种高效的目标检测算法,在视觉分析中具有广泛的应用前景。随着技术的不断发展,YOLO 将不断改进和创新,为计算机视觉领域带来更多的突破和进步。原创 2024-10-09 23:13:05 · 1500 阅读 · 0 评论 -
ONVIF、GB28181技术特点和使用场景分析
ONVIF(Open Network Video Interface Forum)即开放型网络视频接口论坛,是一个全球性的开放性行业论坛,旨在推动基于网络的物理安防产品的互操作性。好多开发者希望搞明白ONVIF和GB28181的区别和各自适合的场景,为什么大牛直播SDK只做了GB28181接入端,没有做ONVIF?本文就二者差别,做个大概的介绍。GB28181 即《公共安全视频监控联网系统信息传输、交换、控制技术要求》,是中国国家标准,在视频监控领域发挥着重要作用。原创 2024-09-30 15:42:02 · 1516 阅读 · 0 评论 -
鸿蒙操作系统(HarmonyOS)生态与机遇
在物联网时代,各种智能设备层出不穷,鸿蒙系统的分布式特性使其能够很好地适应这一趋势,实现不同设备之间的高效互联和协同工作,为万物互联奠定了基础,具有广阔的发展前景。:可作为智能家居的核心 “大脑”,实现家庭中各种设备如灯光、空调、电视、窗帘等的互联互通和智能控制,为用户打造便捷、舒适的智能家居体验,推动智能家居行业的发展。:微内核仅包含操作系统最基本的功能模块,具有更高的安全性和稳定性,降低了系统被攻击的风险,同时也提高了系统的运行效率,能更好地保障用户数据和隐私安全。原创 2024-09-23 00:42:36 · 1928 阅读 · 0 评论 -
拥抱变化之FFmpeg 7.0与VVC
相比于之前的编码标准,VVC在相同视频质量下能够显著减少数据传输和存储的带宽需求,为高清、超高清甚至8K视频内容的传输和播放提供了强有力的支持。:VVC采用了一系列新的编码技术和工具,如更灵活的块划分方法(如Multiple-Type Tree,MTT)、更多的帧内预测模式、增强的帧间预测技术等,这些技术共同提升了VVC的编码效率和视频质量。此外,VVC标准的应用还需要考虑视频内容的版权保护等问题。然而,随着技术的不断进步和VVC标准的不断演进,我们可以期待更高的压缩性能、更好的视频质量和更广泛的应用。原创 2024-09-21 19:53:01 · 1403 阅读 · 0 评论 -
GB28181和SIP网关优缺点分析
GB28181和SIP网关各有其优缺点,在实际应用中需要根据具体需求和场景进行选择。对于需要实现视频监控系统的互联互通和统一管理的场景,GB28181是一个较好的选择;而对于需要实现跨网络、跨协议通信的场景,SIP网关则具有更大的优势。原创 2024-09-13 10:58:43 · 481 阅读 · 0 评论 -
如何实现视频数据的PES打包和传输?
实现视频的PES(Packetized Elementary Stream)打包和传输涉及多个步骤,主要包括视频数据的编码、PES打包、以及通过网络协议的传输。使用视频编码器(如H.264、H.265等)对原始视频数据进行编码,生成编码后的视频码流(ES,Elementary Stream)。将ES包的数据(即编码后的视频数据)添加到PES包中,PES包由PES头部和负载(payload)组成。如果视频数据需要保密传输,可以在PES打包过程中加入加密控制字段,对视频数据进行加密处理。原创 2024-09-12 21:53:19 · 520 阅读 · 0 评论 -
I420和YV12有什么区别?
I420和YV12是YUV420颜色编码格式中的两种不同存储方式,它们之间的主要区别在于色度分量U和V的存储顺序。原创 2024-09-11 17:50:01 · 559 阅读 · 0 评论 -
AVC编码规格之Baseline、Main、High profile区别
规格功能特点应用场景Baseline支持I/P帧,无交错和CAVLC低阶或需要额外容错的应用,如视频通话、手机视频Main支持I/P/B帧,无交错和交错,CAVLC和CABAC主流消费类电子产品规格,如mp4、便携视频播放器、PSP、iPodHigh在Main基础上增加高级编码工具,如8x8内部预测、自定义量化等对视频质量和编码效率要求极高的场景,如广播、视频碟片存储、高清电视。原创 2024-09-11 11:38:44 · 736 阅读 · 0 评论 -
如何看待2020年的最新国际视频编解码标准H.266?
H.266作为最新一代国际视频编码标准,在压缩效率、新编码工具与技术改进、支持新型视频类型和应用等方面都展现出了显著的优势。然而,其推广和应用也面临着专利许可等挑战。未来,随着技术的不断发展和完善,H.266有望在视频编码领域发挥更大的作用。原创 2024-09-11 11:26:46 · 833 阅读 · 0 评论 -
细数H.264 H.265 H.266区别
H.264:也称为AVC(Advanced Video Coding),是MPEG-4的第十部分,由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT)提出的高度压缩数字视频编解码器标准。H.264以其高压缩比和广泛的兼容性成为目前最普遍、用途最广泛的编码格式。H.265:也称为HEVC(High Efficiency Video Coding),是H.264的后继产品,旨在提供更高的压缩效率和更好的图像质量。原创 2024-09-11 11:12:03 · 2331 阅读 · 0 评论 -
C++11 14 17 20 23进化史
C++11、C++14、C++17、C++20和C++23是C++语言标准的不同版本,它们之间在功能、特性和语法上存在一些区别。原创 2024-09-09 21:46:43 · 1075 阅读 · 0 评论 -
C++为什么要引入智能指针?
C++ 引入智能指针是为了更好地管理动态分配的内存,减少内存泄漏、野指针和异常安全等问题,提高代码的安全性和可靠性原创 2024-09-09 21:42:12 · 804 阅读 · 0 评论 -
CopyOnWriteArrayList技术探究
CopyOnWriteArrayList的优势在于可以保证线程安全的同时,不阻塞读操作,但是这仅限于读多写少的情况,在写多读少的情况下,或者写入的对象占用内容较大时,不建议使用。原创 2024-08-14 23:41:40 · 181 阅读 · 0 评论 -
多路RTSP转RTMP推送方案的两个选择
RTSP转RTMP模块设计,可以用ffmpeg直接命令行转发,也可以用方案二的非常成熟的转发设计,ffmpeg转发,需要有一定的代码基础,有问题的话,bug修复需要对底层逻辑非常了解才行,方案二,技术成熟,二次开发难度不大,很同意集成到自己现有系统,感兴趣的开发者,可以单独跟我沟通交流。原创 2024-08-09 10:53:14 · 1364 阅读 · 0 评论 -
Linux平台x86_64|aarch64架构如何实现轻量级RTSP服务
我们在做Linux平台x86_64架构或aarch64架构的推送模块的时候,有公司提出这样的技术需求,希望在Linux平台,实现轻量级RTSP服务,实现对摄像头或屏幕对外RTSP拉流,同步到大屏上去。[V4L2摄像头]支持V4L2摄像头设备选择(设备文件名范围:[/dev/video0, /dev/video63])、分辨率设置、帧率设置;[屏幕/V4L2摄像头]支持帧率、关键帧间隔(GOP)、码率(bit-rate)设置;[V4L2摄像头]支持水平反转、垂直反转、0° 90° 180° 270°旋转;原创 2024-07-05 15:19:22 · 487 阅读 · 0 评论 -
Linux平台下RTSP|RTMP播放器如何跟python交互投递RGB数据供视觉算法分析
Linux平台RTSP、RTMP播放器数据跟python交互,两种方式均可,bitmap实现,也不麻烦,需要注意的时候,由于解码后的单帧数据比较大,建议适当控制导出的bitmap文件数。原创 2024-06-28 17:12:54 · 474 阅读 · 0 评论 -
拉取RTSP流后的几个去向探讨(播放|转RTMP|轻量级RTSP服务|本地录制|GB28181)
Android平台拉取RTSP流后,有了数据源,开发者可以在一个推送实例中,转推到不同的业务场景,实现高效率低延迟的数据转发。原创 2024-01-31 15:41:33 · 635 阅读 · 0 评论 -
Android端获取设备IP地址代码
当然有些场景下,不一定可以拿到设备IP,这时候,需要手动设置IP地址到模块。原创 2023-11-26 12:36:34 · 703 阅读 · 0 评论 -
什么是TCP粘包?如何避免TCP粘包?
4. 使用消息协议:定义自己的消息协议(如使用特定格式的消息头),在发送和接收数据时,按照协议规定的格式进行打包和拆包。2. 固定长度:固定每个数据包的长度,无论实际数据有多少,都按照固定的长度进行发送和接收。TCP粘包是指发送方在发送数据时,由于网络传输的特性,多个数据包可能会被接收方一次性接收到,从而导致粘在一起的现象。1. 发送方发送的数据小于TCP缓冲区的大小,导致多个小的数据包被合并成一个大的数据包发送。2. 发送方快速连续发送多个数据包,接收方在一次接收中接收到了多个数据包。原创 2023-10-28 00:18:59 · 627 阅读 · 0 评论 -
C++智能指针之shared_ptr原理和应用举例
当ptr2和ptr3超出作用域时,引用计数减1,但由于ptr1仍然存在,所以MyClass对象不会被销毁。当ptr1超出作用域时,引用计数为0,MyClass对象会被自动释放,析构函数调用打印出相应的信息。3. shared_ptr在对象不再需要时自动释放,无需手动delete,避免了悬空指针和重复释放的问题。1. shared_ptr可以通过复制来共享对象的所有权,多个指针可以同时指向同一个对象。3. 当一个新的shared_ptr指向一个对象时,引用计数加1。5. 当引用计数为0时,对象会被自动释放。原创 2023-10-26 23:49:40 · 259 阅读 · 0 评论 -
如何使用C++11原子操作实现自旋锁
C++自旋锁是一种低层次的同步原语,用于保护共享资源的访问。自旋锁是一种轻量级的锁,适用于短时间的资源锁定。自旋锁的特点:当一个线程尝试获取已经被另一个线程占有的自旋锁时,这个线程会进入一个循环(自旋),在这个循环中它不断地检查锁是否已经被释放。如果锁已经被释放,那么该线程就可以获取到锁并执行。如果锁仍然被占用,该线程就会一直处于自旋状态,直到获取到锁。自旋锁的一个重要特点是它不会导致调用者睡眠,如果自旋锁已经被占用,调用者会一直处于忙等待状态,直到能够获取到锁。原创 2023-09-02 22:43:50 · 353 阅读 · 0 评论 -
原子类型AtomicLong用法探究
LongAdder 是把 value 分成若干cell,并发量低的时候,直接 CAS 更新值,成功即结束。并发量高的情况,CAS更新某个cell值和需要时对cell数据扩容,成功结束; 是 Java 提供的一个原子长整型类,提供了对长整型数据的原子性操作。 对象的原子性操作,确保在多线程环境下的数据安全性。 的原子性操作,我们可以在多线程环境下安全地递增 。 的使用方法和功能与标准 Java 中的 。 可以确保对长整型数据的操作是线程安全的。,避免了竞态条件的问题。原创 2023-07-22 19:15:29 · 662 阅读 · 0 评论 -
C++设计模式之责任链模式
当需要将请求发送给多个对象处理时或需要动态指定处理请求的对象集合时,如果在不明确接收者的情况下,将请求发送给多个对象中的一个或多个时,可以使用责任链模式。责任链模式将发送者和接收者解耦,提高了系统的灵活性和可扩展性。将这些接受处理的对象连成一条链,并沿着该链处理请求,收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。,它包含一个责任链,可以将请求传递给链上的每个处理者。在测试代码中,我们创建了处理者对象和请求者对象,并将责任链设置为。,以及两个具体的处理者类。原创 2023-07-20 23:50:50 · 170 阅读 · 0 评论 -
C++实现设计模式之观察者模式
观察者模式是一种一对多的以来关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并被自动更新。它的主体是通知的发布者,发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知,将观察者和被观察的对象分离开。然后,当主题的状态改变时,所有附加的观察者都会收到通知并执行相应的操作。是具体的主题实现,它维护一个观察者列表,并在状态改变时通知所有观察者。是具体的观察者实现,它在被通知时执行特定的操作。在主函数中,我们创建了一个。是观察者接口,。实例,并将三个。原创 2023-07-19 23:49:48 · 221 阅读 · 0 评论 -
C++14新特性扫盲探究
闲暇之时,聊到C++14,实际上C++14相对之前的11并没有太大的改动,或者说更像C++11标准基础上的查漏补缺,C++14之后,还有17、20甚至23,所以说,C++14更像个过渡版本。原创 2023-07-12 23:39:44 · 283 阅读 · 0 评论 -
编程语言比拼之Java VS C++
Java和C++各有优势,选择哪种语言取决于你的应用场景和个人需求。如果你关注跨平台性、生态系统和开发效率,Java可能是更好的选择当然学c和c++会看你想从事什么职业,但一般来说c++会比java难学一些。如果以后想从事java方面的程序员工作,那么直接学习java比较好。无法简单地回答Java程序员工资高还是C++程序员工资高的问题。Java程序员工资和C++程序员工资的高低因人而异,具体取决于个人技能、经验、公司行业和地区等因素。Java和C++都是非常受欢迎的编程语言,各有各的优势和适用场景。原创 2023-07-10 23:22:34 · 518 阅读 · 0 评论 -
Android AtomicBoolean浅析
是一个非常有用的原子类,在 Android 开发中可以用于处理多线程环境下的布尔类型的操作,提供线程安全性并且简单易用。 是一个原子布尔类,用于在多线程环境中安全地进行布尔类型的操作。这个方法是一个原子性的操作,会在设置新值之前获取当前的旧值,并且设置新值。 方法可以用于检查和设置布尔类型的值,而 。,那么执行一些操作。,并将其初始值设置为 。 方法中,我们使用 。 的两个主要方法:。以下是一些常见的 。 的值设置为 。 的原本值为 。 的值修改为 。原创 2023-07-09 12:50:18 · 567 阅读 · 1 评论 -
设计模式八大原则知多少
这些原则都是通用的设计原则,可以帮助我们设计出更好的软件系统。在实际应用中,我们需要根据具体的场景和问题来选择合适的原则。设计模式是一种通用的解决问题的经验,可以帮助我们设计出可重用、可维护和可扩展的软件。原创 2023-07-09 11:43:42 · 211 阅读 · 0 评论 -
如何用C++11实现观察者模式
当一个对象状态发生改变时,它的依赖者都会收到通知并自动更新。在上面的例子中,我们使用了C++11的一些特性,如auto关键字推断类型、unique_ptr智能指针和范围for循环。这样可以使代码更加简洁、安全和易于维护。现在,我们可以创建一个主题对象,并注册多个观察者对象。当主题对象的状态发生改变时,它会通知所有的观察者对象。首先,我们需要创建一个观察者接口,其中包含一个更新方法。这个接口可以被多个观察者类实现,从而实现多态。接下来,我们可以创建一个具体的观察者类,它实现观察者接口,并注册到主题对象中。原创 2023-07-08 22:42:26 · 795 阅读 · 0 评论 -
如何用C语言实现多态?
在运行时,程序会分别输出 "Drawing a circle..." 和 "Drawing a rectangle...",这表明不同的对象调用了不同的绘制函数。多态(Polymorphism)是指面向对象程序运行时,相同的消息可能会送给多个不同的类之对象,系统依据对象所属类,引发对应类的方法,而有不同的行为。 的对象,并将它们传递给基类的绘制函数 。 结构体作为基类,它包含一个指向 。,它们都包含了一个继承自基类的 。在上面的示例中,我们定义了一个 。 函数中,我们创建了 。原创 2023-07-08 22:22:45 · 775 阅读 · 1 评论 -
C++学习之-析构函数必须为虚函数吗?
既然这样,是不是C++默认的析构函数设计成虚函数更合适?答案是否定的,大家都知道,虚函数需要额外的虚函数表和虚表指针,占用额外的内存,如果类的设计不考虑继承,把析构函数设置成虚函数无疑是浪费内存。当父类指针释放子类对象时,如果父类的析构函数不是虚函数,子类的析构函数可能调不到(指针类型是父类,所以直接调用父类的析构函数),从而导致内存泄漏,这类代码实在太简单,这里就不再贴实例代码了。析构函数是不是必须要为虚函数?原创 2022-09-06 09:28:17 · 1815 阅读 · 0 评论 -
C++11/14/17中提供的mutex系列区别
C++11/14/17中提供的mutex系列类型如下:互斥量C++版本作用mutexC++11基本的互斥量timed_mutexC++11timed_mutex带超时功能。在规定的等待时间内,没有获取锁,线程不会一直阻塞,代码会继续执行recursive_mutexC++11递归锁,允许在同一个线程中同一个互斥量多次被 lock() ,用于可能被连续多次上锁(期间未解锁)的情况,效率要比mutex低std::mutex 及其变种不允许同一个线程对互斥量多次上锁,而 std::recursive_mutex原创 2022-06-16 11:17:16 · 294 阅读 · 0 评论 -
C++17新特性之try_emplace与insert_or_assign
由于std::map中,元素的key是唯一的,我们经常遇到这样的场景,向map中插入元素时,先检测map指定的key是否存在,不存在时才做插入操作,如果存在,直接取出来使用,或者key不存在时,做插入操作,存在时做更新操作。通用的做法,可以直接用emplace操作,判断指定的key是否存在,如果不存在,则插入元素,当元素存在的时候,emplace依然会构造一次带待插入元素,判断不需要插入后,将该元素析构,这样导致的后果是,产生了多余的构造和析构操作。鉴于此,C++17引入了std::try_emplace,原创 2022-06-03 22:54:15 · 1933 阅读 · 0 评论 -
探究C++11智能指针之std::unique_ptr
谈起C++,它被公认为最难学的编程语言之一,不仅语法知识点广泛,细节内容之多,学习难度和学习周期也长,导致好多新入行的开发者对C++“敬而远之”,甚至“从入门到放弃”。自C++11开始,好多C++程序员慢慢的感受到了C++的魅力所在,似乎难度也越来越小。 本文要讲的是C++11引入的智能指针之std::unique_ptr。std::unique_ptr系C++11引入的智能指针,拥有资源的唯一所有权,头文件 #include 。unique_ptr指针指向的堆内存空间的引用计数为 1,如原创 2022-06-01 21:53:02 · 2343 阅读 · 0 评论 -
2022年了,该学C++还是Java?
最近好多朋友私信我,C++好不好学?学C++好还是Java好?我的回答是:C++不好学,但你觉得C++不好学的话,Java也不好学。因为C++难是难在语言本身,java难是难在各种框架和库。C++学习进阶比较陡, 对新手不友好,新手写起来代码,心智负担很重,短期内很难出活。就像网上段子说的一样,C++前几个月学习下来,看完C++ primer类似的入门书,觉得也不过如此,3-4年的时候,开始怀疑自己是不是适合搞C++。7-8年的时候,觉得学有所成,半个专家了,10年以上,突然感觉也.原创 2022-05-16 17:22:28 · 2622 阅读 · 0 评论 -
C++11特性之std:call_once介绍
std:call_once是C++11引入的新特性,如需使用,只需要#include <mutex>即可,简单来说std:call_once的作用,确保函数或代码片段在多线程环境下,只需要执行一次,常用的场景如Init()操作或一些系统参数的获取等。相对来说,std::call_once用法比较简单,配合std::once_flag即可实现,废话不多说,上代码:#include "stdafx.h"#include <iostream>#include <thre原创 2022-05-12 17:18:04 · 997 阅读 · 0 评论