Linux 下的实时流媒体(RTP)编程

WebRTC音频系统 之audio技术栈简介-1 标准和源码是研究WebRTC的第一手资料,而标准和源码也是在持续的演进,在编译native源的该时候,可以生成各个模块的测试二进制程序,通过这些二进制程序熟悉各个模块的使用方法,比如APM模块的可执行二进制测试程序是audioproc_f,各个模块的组成见1.4小节,图1-3,测试程序包括了音视频以及网络部分,和native 测试app,其测试程序见下图红色部分:图1-1 MacOS上WebRTC native编译结果。 阅读详情

流媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下载边播放的方式,它是视频会议、IP 电话等应用场合的技术基础。RTP 是进行实时流媒体传输的标准协议和关键技术,本文介绍如何在 Linux 下利用 JRTPLIB 进行实时流媒体编程。

一、流媒体简介

随着 Internet 的日益普及,在网络上传输的数据已经不再局限于文字和图形,而是逐渐向声音和视频等多媒体格式过渡。目前在网络上传输音频/视频(Audio/Video,简称 A/V)等多媒体文件时,基本上只有下载和流式传输两种选择。通常说来,A/V 文件占据的存储空间都比较大,在带宽受限的网络环境中下载可能要耗费数分钟甚至数小时,所以这种处理方法的延迟很大。如果换用流式传输的话,声音、影像、动画等多媒体文件将由专门的流媒体服务器负责向用户连续、实时地发送,这样用户可以不必等到整个文件全部下载完毕,而只需要经过几秒钟的启动延时就可以了,当这些多媒体数据在客户机上播放时,文件的剩余部分将继续从流媒体服务器下载。

流(Streaming)是近年在 Internet 上出现的新概念,其定义非常广泛,主要是指通过网络传输多媒体数据的技术总称。流媒体包含广义和狭义两种内涵:广义上的流媒体指的是使音频和视频形成稳定和连续的传输流和回放流的一系列技术、方法和协议的总称,即流媒体技术;狭义上的流媒体是相对于传统的下载-回放方式而言的,指的是一种从 Internet 上获取音频和视频等多媒体数据的新方法,它能够支持多媒体数据流的实时传输和实时播放。通过运用流媒体技术,服务器能够向客户机发送稳定和连续的多媒体数据流,客户机在接收数据的同时以一个稳定的速率回放,而不用等数据全部下载完之后再进行回放。

由于受网络带宽、计算机处理能力和协议规范等方面的限制,要想从 Internet 上下载大量的音频和视频数据,无论从下载时间和存储空间上来讲都是不太现实的,而流媒体技术的出现则很好地解决了这一难题。目前实现流媒体传输主要有两种方法:顺序流(progressive streaming)传输和实时流(realtime streaming)传输,它们分别适合于不同的应用场合。

顺序流传输

顺序流传输采用顺序下载的方式进行传输,在下载的同时用户可以在线回放多媒体数据,但给定时刻只能观看已经下载的部分,不能跳到尚未下载的部分,也不能在传输期间根据网络状况对下载速度进行调整。由于标准的 HTTP 服务器就可以发送这种形式的流媒体,而不需要其他特殊协议的支持,因此也常常被称作 HTTP 流式传输。顺序流式传输比较适合于高质量的多媒体片段,如片头、片尾或者广告等。

实时流传输

实时流式传输保证媒体信号带宽能够与当前网络状况相匹配,从而使得流媒体数据总是被实时地传送,因此特别适合于现场事件。实时流传输支持随机访问,即用户可以通过快进或者后退操作来观看前面或者后面的内容。从理论上讲,实时流媒体一经播放就不会停顿,但事实上仍有可能发生周期性的暂停现象,尤其是在网络状况恶化时更是如此。与顺序流传输不同的是,实时流传输需要用到特定的流媒体服务器,而且还需要特定网络协议的支持。

二、流媒体协议

实时传输协议(Real-time Transport Protocol,PRT)是在 Internet 上处理多媒体数据流的一种网络协议,利用它能够在一对一(unicast,单播)或者一对多(multicast,多播)的网络环境中实现传流媒体数据的实时传输。RTP 通常使用 UDP 来进行多媒体数据的传输,但如果需要的话可以使用 TCP 或者 ATM 等其它协议,整个 RTP 协议由两个密切相关的部分组成:RTP 数据协议和 RTP 控制协议。实时流协议(Real Time Streaming Protocol,RTSP)最早由 Real Networks 和 Netscape 公司共同提出,它位于 RTP 和 RTCP 之上,其目的是希望通过 IP 网络有效地传输多媒体数据。

2.1 RTP 数据协议

RTP 数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前 12 个字节的含义是固定的,而负载则可以是音频或者视频数据。RTP 数据报的头部格式如图 1 所示: 
 

                                                                       图 1 RTP 头部格式



其中比较重要的几个域及其意义如下:

? CSRC 记数(CC)  表示 CSRC 标识的数目。CSRC 标识紧跟在 RTP 固定头部之后,用来表示 RTP 数据报的来源,RTP 协议允许在同一个会话中存在多个数据源,它们可以通过 RTP 混合器合并为一个数据源。例如,可以产生一个 CSRC 列表来表示一个电话会议,该会议通过一个 RTP 混合器将所有讲话者的语音数据组合为一个 RTP 数据源。
? 负载类型(PT)  标明 RTP 负载的格式,包括所采用的编码算法、采样频率、承载通道等。例如,类型 2 表明该 RTP 数据包中承载的是用 ITU G.721 算法编码的语音数据,采样频率为 8000Hz,并且采用单声道。
? 序列号  用来为接收方提供探测数据丢失的方法,但如何处理丢失的数据则是应用程序自己的事情,RTP协议本身并不负责数据的重传。
? 时间戳  记录了负载中第一个字节的采样时间,接收方能够时间戳能够确定数据的到达是否受到了延迟抖动的影响,但具体如何来补偿延迟抖动则是应用程序自己的事情。

从 RTP 数据报的格式不难看出,它包含了传输媒体的类型、格式、序列号、时间戳以及是否有附加数据等信息,这些都为实时的流媒体传输提供了相应的基础。RTP 协议的目的是提供实时数据(如交互式的音频和视频)的端到端传输服务,因此在 RTP 中没有连接的概念,它可以建立在底层的面向连接或面向非连接的传输协议之上;RTP 也不依赖于特别的网络地址格式,而仅仅只需要底层传输协议支持组帧(Framing)和分段(Segmentation)就足够了;另外 RTP 本身还不提供任何可靠性机制,这些都要由传输协议或者应用程序自己来保证。在典型的应用场合下,RTP 一般是在传输协议之上作为应用程序的一部分加以实现的,如图 2 所示:




 
相关协议
RTCP 、 RTSP 、 UDP 、 TCP 、 IP
组织来源
RTP 由 IETF ( www.ietf.org )定义在 RFC 3550 和 3551 中。
相关链接
http://www.javvin.com/protocol/rfc3550.pdf: RTP: A Transport Protocol for Real-Time Applications
http://www.javvin.com/protocol/rfc3551.pdf: RTP Profile for Audio and Video Conferences with Minimal Control

图2 RTP与各种网络协议的关系


2.2 RTCP 控制协议

RTCP 控制协议需要与 RTP 数据协议一起配合使用,当应用程序启动一个 RTP 会话时将同时占用两个端口,分别供 RTP 和 RTCP 使用。RTP 本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由 RTCP 来负责完成。通常 RTCP 会采用与 RTP 相同的分发机制,向会话中的所有成员周期性地发送控制信息,应用程序通过接收这些数据,从中获取会话参与者的相关资料,以及网络状况、分组丢失概率等反馈信息,从而能够对服务质量进行控制或者对网络状况进行诊断。

RTCP 协议的功能是通过不同的 RTCP 数据报来实现的,主要有如下几种类型:

? SR  发送端报告,所谓发送端是指发出 RTP 数据报的应用程序或者终端,发送端同时也可以是接收端。
? RR  接收端报告,所谓接收端是指仅接收但不发送 RTP 数据报的应用程序或者终端。
? SDES  源描述,主要功能是作为会话成员有关标识信息的载体,如用户名、邮件地址、电话号码等,此外还具有向会话成员传达会话控制信息的功能。
? BYE  通知离开,主要功能是指示某一个或者几个源不再有效,即通知会话中的其他成员自己将退出会话。
? APP  由应用程序自己定义,解决了 RTCP 的扩展性问题,并且为协议的实现者提供了很大的灵活性。

RTCP 数据报携带有服务质量监控的必要信息,能够对服务质量进行动态的调整,并能够对网络拥塞进行有效的控制。由于 RTCP 数据报采用的是多播方式,因此会话中的所有成员都可以通过 RTCP 数据报返回的控制信息,来了解其他参与者的当前情况。

在一个典型的应用场合下,发送媒体流的应用程序将周期性地产生发送端报告 SR,该 RTCP 数据报含有不同媒体流间的同步信息,以及已经发送的数据报和字节的计数,接收端根据这些信息可以估计出实际的数据传输速率。另一方面,接收端会向所有已知的发送端发送接收端报告 RR,该 RTCP 数据报含有已接收数据报的最大序列号、丢失的数据报数目、延时抖动和时间戳等重要信息,发送端应用根据这些信息可以估计出往返时延,并且可以根据数据报丢失概率和时延抖动情况动态调整发送速率,以改善网络拥塞状况,或者根据网络状况平滑地调整应用程序的服务质量。

2.3 RTSP 实时流协议

作为一个应用层协议,RTSP 提供了一个可供扩展的框架,它的意义在于使得实时流媒体数据的受控和点播变得可能。总的说来,RTSP是一个流媒体表示协议,主要用来控制具有实时特性的数据发送,但它本身并不传输数据,而是必须依赖于下层传输协议所提供的某些服务。RTSP可以对流媒体提供诸如播放、暂停、快进等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与RTP间的交互操作。

RTSP在制定时较多地参考了HTTP/1.1协议,甚至许多描述与 HTTP/1.1 完全相同。RTSP 之所以特意使用与 HTTP/1.1 类似的语法和操作,在很大程度上是为了兼容现有的 Web 基础结构,正因如此,HTTP/1.1 的扩展机制大都可以直接引入到 RTSP 中。

由 RTSP 控制的媒体流集合可以用表示描述(Presentation Description)来定义,所谓表示是指流媒体服务器提供给客户机的一个或者多个媒体流的集合,而表示描述则包含了一个表示中各个媒体流的相关信息,如数据编码/解码算法、网络地址、媒体流的内容等。

虽然 RTSP 服务器同样也使用标识符来区别每一流连接会话(Session),但RTSP连接并没有被绑定到传输层连接(如 TCP 等),也就是说在整个 RTSP 连接期间,RTSP 用户可打开或者关闭多个对 RTSP 服务器的可靠传输连接以发出 RTSP 请求。此外,RTSP 连接也可以基于面向无连接的传输协议(如 UDP 等)。

RTSP 协议目前支持以下操作:

? 检索媒体  允许用户通过 HTTP 或者其它方法向媒体服务器提交一个表示描述。如表示是组播的,则表示描述就包含用于该媒体流的组播地址和端口号;如果表示是单播的,为了安全在表示描述中应该只提供目的地址。
? 邀请加入  媒体服务器可以被邀请参加正在进行的会议,或者在表示中回放媒体,或者在表示中录制全部媒体或其子集,非常适合于分布式教学。
? 添加媒体  通知用户新加入的可利用媒体流,这对现场讲座来讲显得尤其有用。与 HTTP/1.1 类似,RTSP 请求也可以交由代理、通道或者缓存来进行处理。

三、流媒体编程

RTP 是目前解决流媒体实时传输问题的最好办法,如果需要在 Linux 平台上进行实时流媒体编程,可以考虑使用一些开放源代码的 RTP 库,如 LIBRTP、JRTPLIB 等。JRTPLIB 是一个面向对象的 RTP 库,它完全遵循 RFC 1889 设计,在很多场合下是一个非常不错的选择,下面就以 JRTPLIB 为例,讲述如何在 Linux 平台上运用 RTP 协议进行实时流媒体编程。

3.1 环境搭建

JRTPLIB 是一个用 C++ 语言实现的 RTP 库,目前已经可以运行在 Windows、Linux、FreeBSD、Solaris、Unix和VxWorks 等多种操作系统上。要为 Linux 系统安装 JRTPLIB,首先从 JRTPLIB 的网站( http://lumumba.luc.ac.be/jori/jrtplib/jrtplib.html)下载最新的源码包,此处使用的是 jrtplib-2.7b.tar.bz2。假设下载后的源码包保存在 /usr/local/src 目录下,执行下面的命令可以对其进行解压缩:

[root@linuxgam src]# bzip2 -dc jrtplib-2.7b.tar.bz2 | tar xvf - 


接下去需要对 JRTPLIB 进行配置和编译:

[root@linuxgam src]# cd jrtplib-2.7 
[root@linuxgam jrtplib-2.7b]# ./configure
[root@linuxgam jrtplib-2.7b]# make


最后再执行如下命令就可以完成 JRTPLIB 的安装:

[root@linuxgam jrtplib-2.7b]# make install 


3.2 初始化

在使用 JRTPLIB 进行实时流媒体数据传输之前,首先应该生成 RTPSession 类的一个实例来表示此次 RTP 会话,然后调用 Create() 方法来对其进行初始化操作。RTPSession 类的 Create() 方法只有一个参数,用来指明此次 RTP 会话所采用的端口号。清单 1 给出了一个最简单的初始化框架,它只是完成了 RTP 会话的初始化工作,还不具备任何实际的功能。

代码清单 1:initial.cpp

#include "rtpsession.h" 

int main(void)
{
RTPSession sess;
sess.Create(5000);
return 0;
}


如果 RTP 会话创建过程失败,Create() 方法将会返回一个负数,通过它虽然可以很容易地判断出函数调用究竟是成功的还是失败的,但却很难明白出错的原因到底什么。JRTPLIB 采用了统一的错误处理机制,它提供的所有函数如果返回负数就表明出现了某种形式的错误,而具体的出错信息则可以通过调用 RTPGetErrorString() 函数得到。RTPGetErrorString( )函数将错误代码作为参数传入,然后返回该错误代码所对应的错误信息。清单 2 给出了一个更加完整的初始化框架,它可以对 RTP 会话初始化过程中所产生的错误进行更好的处理:

代码清单 2:framework.cpp

#include <stdio.h> 
#include "rtpsession.h"

int main(void)
{
RTPSession sess;
int status;
char* msg;

sess.Create(6000);
msg = RTPGetErrorString(status);
printf("Error String: %s//n", msg);
return 0;
}


设置恰当的时戳单元,是 RTP 会话初始化过程所要进行的另外一项重要工作,这是通过调用 RTPSession 类的 SetTimestampUnit() 方法来实现的,该方法同样也只有一个参数,表示的是以秒为单元的时戳单元。例如,当使用 RTP 会话传输 8000Hz 采样的音频数据时,由于时戳每秒钟将递增 8000,所以时戳单元相应地应该被设置成 1/8000:

sess.SetTimestampUnit(1.0/8000.0); 


3.3 数据发送

当 RTP 会话成功建立起来之后,接下去就可以开始进行流媒体数据的实时传输了。首先需要设置好数据发送的目标地址,RTP 协议允许同一会话存在多个目标地址,这可以通过调用 RTPSession 类的 AddDestination()、DeleteDestination() 和 ClearDestinations() 方法来完成。例如,下面的语句表示的是让 RTP 会话将数据发送到本地主机的 6000 端口:

unsigned long addr = ntohl(inet_addr("127.0.0.1")); 
sess.AddDestination(addr, 6000);


目标地址全部指定之后,接着就可以调用 RTPSession 类的 SendPacket() 方法,向所有的目标地址发送流媒体数据。SendPacket() 是 RTPSession 类提供的一个重载函数,它具有下列多种形式:

int SendPacket(void *data,int len) 
int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc)
int SendPacket(void *data,int len,unsigned short hdrextID,void *hdrextdata,int numhdrextwords)
int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc,unsigned
short hdrextID,void *hdrextdata,int numhdrextwords)


SendPacket() 最典型的用法是类似于下面的语句,其中第一个参数是要被发送的数据,而第二个参数则指明将要发送数据的长度,再往后依次是 RTP 负载类型、标识和时戳增量。

sess.SendPacket(buffer, 5, 0, false, 10); 


对于同一个 RTP 会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB 允许将它们设置为会话的默认参数,这是通过调用 RTPSession 类的 SetDefaultPayloadType()、SetDefaultMark() 和 SetDefaultTimeStampIncrement() 方法来完成的。为 RTP 会话设置这些默认参数的好处是可以简化数据的发送,例如,如果为 RTP 会话设置了默认参数:

sess.SetDefaultPayloadType(0); 
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);


之后在进行数据发送时只需指明要发送的数据及其长度就可以了:

sess.SendPacket(buffer, 5); 


3.4 数据接收

对于流媒体数据的接收端,首先需要调用 RTPSession 类的 PollData() 方法来接收发送过来的 RTP 或者 RTCP 数据报。由于同一个 RTP 会话中允许有多个参与者(源),你既可以通过调用 RTPSession 类的 GotoFirstSource() 和 GotoNextSource() 方法来遍历所有的源,也可以通过调用 RTPSession 类的 GotoFirstSourceWithData() 和 GotoNextSourceWithData() 方法来遍历那些携带有数据的源。在从 RTP 会话中检测出有效的数据源之后,接下去就可以调用 RTPSession 类的 GetNextPacket() 方法从中抽取 RTP 数据报,当接收到的 RTP 数据报处理完之后,一定要记得及时释放。下面的代码示范了该如何对接收到的 RTP 数据报进行处理:

if (sess.GotoFirstSourceWithData()) { 
do {
RTPPacket *pack;
pack = sess.GetNextPacket();
// 处理接收到的数据
delete pack;
} while (sess.GotoNextSourceWithData());
}


JRTPLIB 为 RTP 数据报定义了三种接收模式,其中每种接收模式都具体规定了哪些到达的 RTP 数据报将会被接受,而哪些到达的 RTP 数据报将会被拒绝。通过调用 RTPSession 类的 SetReceiveMode() 方法可以设置下列这些接收模式:
? RECEIVEMODE_ALL  缺省的接收模式,所有到达的 RTP 数据报都将被接受;
? RECEIVEMODE_IGNORESOME  除了某些特定的发送者之外,所有到达的 RTP 数据报都将被接受,而被拒绝的发送者列表可以通过调用 AddToIgnoreList()、DeleteFromIgnoreList() 和 ClearIgnoreList() 方法来进行设置;
? RECEIVEMODE_ACCEPTSOME  除了某些特定的发送者之外,所有到达的 RTP 数据报都将被拒绝,而被接受的发送者列表可以通过调用 AddToAcceptList ()、DeleteFromAcceptList 和 ClearAcceptList () 方法来进行设置。

3.5 控制信息

JRTPLIB 是一个高度封装后的 RTP 库,程序员在使用它时很多时候并不用关心 RTCP 数据报是如何被发送和接收的,因为这些都可以由 JRTPLIB 自己来完成。只要 PollData() 或者 SendPacket() 方法被成功调用,JRTPLIB 就能够自动对到达的 RTCP 数据报进行处理,并且还会在需要的时候发送 RTCP 数据报,从而能够确保整个 RTP 会话过程的正确性。

而另一方面,通过调用 RTPSession 类提供的 SetLocalName()、SetLocalEMail()、SetLocalLocation()、SetLocalPhone()、SetLocalTool() 和 SetLocalNote() 方法,JRTPLIB 又允许程序员对RTP会话的控制信息进行设置。所有这些方法在调用时都带有两个参数,其中第一个参数是一个 char 型的指针,指向将要被设置的数据;而第二个参数则是一个 int 型的数值,表明该数据中的前面多少个字符将会被使用。例如下面的语句可以被用来设置控制信息中的电子邮件地址:

sess.SetLocalEMail("xiaowp@linuxgam.com",19); 


在 RTP 会话过程中,不是所有的控制信息都需要被发送,通过调用 RTPSession 类提供的 EnableSendName()、EnableSendEMail()、EnableSendLocation()、EnableSendPhone()、EnableSendTool() 和 EnableSendNote() 方法,可以为当前 RTP 会话选择将被发送的控制信息。

3.6 实际应用

最后通过一个简单的流媒体发送-接收实例,介绍如何利用 JRTPLIB 来进行实时流媒体的编程。清单 3 给出了数据发送端的完整代码,它负责向用户指定的 IP 地址和端口,不断地发送 RTP 数据包:

代码清单 3:sender.cpp

#include <stdio.h> 
#include <string.h>
#include "rtpsession.h"

// 错误处理函数
void checkerror(int err)
{
if (err < 0) {
char* errstr = RTPGetErrorString(err);
printf("Error:%s//n", errstr);
exit(-1);
}
}

int main(int argc, char** argv)
{
RTPSession sess;
unsigned long destip;
int destport;
int portbase = 6000;
int status, index;
char buffer[128];

if (argc != 3) {
printf("Usage: ./sender destip destport//n");
return -1;
}

// 获得接收端的 IP 地址和端口号
destip = inet_addr(argv[1]);
if (destip == INADDR_NONE) {
printf("Bad IP address specified.//n");
return -1;
}
destip = ntohl(destip);
destport = atoi(argv[2]);

// 创建 RTP 会话
status = sess.Create(portbase);
checkerror(status);

// 指定 RTP 数据接收端
status = sess.AddDestination(destip, destport);
checkerror(status);

// 设置 RTP 会话默认参数
sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);

// 发送流媒体数据
index = 1;
do {
sprintf(buffer, "%d: RTP packet", index ++);
sess.SendPacket(buffer, strlen(buffer));
printf("Send packet !//n");
} while(1);

return 0;
}


清单 4 则给出了数据接收端的完整代码,它负责从指定的端口不断地读取 RTP 数据包:

代码清单 4:receiver.cpp

#include <stdio.h> 
#include "rtpsession.h"
#include "rtppacket.h"

// 错误处理函数
void checkerror(int err)
{
if (err < 0) {
char* errstr = RTPGetErrorString(err);
printf("Error:%s//n", errstr);
exit(-1);
}
}

int main(int argc, char** argv)
{
RTPSession sess;
int localport;
int status;

if (argc != 2) {
printf("Usage: ./sender localport//n");
return -1;
}

// 获得用户指定的端口号
localport = atoi(argv[1]);

// 创建 RTP 会话
status = sess.Create(localport);
checkerror(status);

do {
// 接受 RTP 数据
status = sess.PollData();
// 检索 RTP 数据源
if (sess.GotoFirstSourceWithData()) {
do {
RTPPacket* packet;
// 获取 RTP 数据报
while ((packet = sess.GetNextPacket()) != NULL) {
printf("Got packet !//n");
// 删除 RTP 数据报
delete packet;
}
} while (sess.GotoNextSourceWithData());
}
} while(1);

return 0;
}


本文源码 下载

四、小结

随着多媒体数据在 Internet 上所承担的作用变得越来越重要,需要实时传输音频和视频等多媒体数据的场合也将变得越来越多,如 IP 电话、视频点播、在线会议等。RTP 是用来在 Internet 上进行实时流媒体传输的一种协议,目前已经被广泛地应用在各种场合,JRTPLIB 是一个面向对象的 RTP 封装库,利用它可以很方便地完成 Linux 平台上的实时流媒体编程。

五、参考资源

1. 在 JRTPLIB 的网站 http://lumumba.luc.ac.be/jori/jrtplib/jrtplib.html 上,可以下载到 JRTPLIB 最新的源码包,并且还能找到一些与 RTP 相关的资源。

2. 顾淑珍等编著,宽带增值服务开发实例,北京:机械工业出版社,2002

3. 黄永峰等编著,IP 网络多媒体通信技术,北京:人民邮电出版社,2003 
 

Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1721648 

Linux音视频学习--常见的音视频传输协议及基本概念介绍 一、引言 二、视频格式 ------> 1、RGB ------> 2、RGB常见格式(RGB888、RGB24等) ------> 3、YUV ------------> 2.1、YUV的常见采样格式(YUV422、YUV420等) ------------> 2.2、YUV存储格式(YV12、NV12、NV21等) 三、码流 ------> 1、视频分辨率、码流、帧率、带宽、存储空间 ------> 2、计算方式 一、引言 最近由于跳槽,各种事情比较多,就好久没 阅读详情

相关推荐

P2P技术在音视频开发中的应用

通过建立P2P连接、发起和接收音视频流以及关闭连接,开发人员可以在音视频应用程序中集成P2P技术,提供更高效和稳定的通信体验。P2P技术(Peer-to-Peer)是一种去中心化的通信方式,在音视频开发领域有着广泛的应用。本文将介绍P2P技术在音视频开发中的应用,并提供相应的源代码示例。P2P技术的基本原理是通过将网络中的节点(也称为对等方或peer)连接在一起,使节点能够直接相互通信,实现资源共享和数据传输。在音视频开发中,P2P技术可以用于实现实时的音视频通信和流媒体传输。二、P2P音视频通信的实现。

EtwCpp的博客 363

FFmpeg音视频开发实战6 iOS/Android/windows/Linux

本课程为《FFmpeg音视频开发实战5》的进阶课程,也是终结篇。从第6部分开始,我们进入高阶课程的学习。针对音视频核心功能进一步深化讲解,更多的实际案例,从FFmpeg本地音视频处理,深入UDP网络通讯协议,UDP高效实时视频传输,丢包处理,到OpenGL/ES 特效,滤镜,到webRTC,SIP重量级网络通讯协议框架.以及当前比较流行,未来人才需求量非常大的机器学习,深度学习,移动端人工智能,投入更多的内容。

等保2.0云安全方案落地:从控制项翻译到持续合规巡检

网络安全等级保护2.0(等保2.0)将云计算扩展要求独立成章,明确“三同步”与责任共担模型,为云上业务划定了新的安全基线。云安全方案不再是简单的产品堆叠,而是将抽象的控制项转译为VPC子网隔离、安全组最小授权、多因素认证、密钥轮换与日志留存等可验证的云资源策略。从定级备案、差距分析到主机基线加固,每一步都依赖对云平台原生能力的理解与工程化落地。在完成测评后,仍应通过自动化巡检脚本固化检查项,确保持续合规。本文面向云运维与安全工程师,梳理等保2.0在云上的落地链路,并结合密钥管理与日志审计等实践,帮助团队将合

weixin_33811539的博客 454

P2P实时音视频传输的应用

能打洞成功的网络都能使用p2p,不能打洞成功的网络基本上都是跟路由器类型有关,根据google官方文档,国外92%的情况下都可以p2p,,在国内70~80%的成功率是可以期待的。p是peer的缩写,p2p就是点对点,两个客户端直接进行数据交互,不需要经过服务器转发(relay),这种方式能大大减轻服务端的负载,所以特别视适合大数据的传输,比如实时音视频聊天、在线视频直播、大文件传输以及监控摄像头、可视门锁、可视门铃等安防应用场景。针对长时间开启的远程监控摄像头,必须使用p2p才能保证高并发,并降低的。

hey5178的博客 426

通过JLink下载实现工控MCU批量烧录实战案例

利用JLink下载工具实现高效稳定的工控MCU批量烧录,提升产线效率。案例详细解析了脚本配置与自动化流程,突出jlink下载的可靠性和可扩展性,适用于大规模嵌入式部署场景。

weixin_30205153的博客 812

SUMO仿真教程(5) —— 使用“XML“语言自定义构建路网

文章目录一.简要介绍1.node file2.edge file3.lane definitions(1)路段细分(2)邻近的对向车道(3)删除边或车道4.type file(1)简要概述(2)edge定义中引用type文件的示例(3)指定车辆种类的速度限制5.connections file(1)简要概述:(2)connection的属性参数(3)删除连接(4)设置连接的优先级(5)同一边的多个连接二.演示示例:1.自定义编写node file2.自定义编写edge file3.自定义编写type fil

weixin_50632459的博客 5015

Linux下的实时流媒体编程(RTP,RTCP,RTSP)

流媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下载边播放的方式,它是视频会议、IP电话等应用场合的技术基础。RTP是进行实时流媒体传输的标准协议和关键技术,本文介绍如何在Linux下利用JRTPLIB进行实时流媒体编程。 一、流媒体简介      随着Internet的日益普及,在网络上传输的数据已经不再局限于文字和图形,而是逐渐向声音和视

chenjie0011的专栏 655

kaggle——销量预测的baseline(M5 Forecasting - Accuracy)

前言 在刚刚结束的kaggle比赛M5 Forecasting - Accuracy中,因为是第一次参加,笔者也是花了大量的时间和精力在上面,最终拿到一块银牌(所以我拿到了大学第一个考试挂科。。。求求电磁场老师高抬贵手给点平时分放我一马吧。。。早上看到kaggle成绩异常兴奋,中午考完直接爆炸=。=),当然运气占了很大因素,这次比赛private leadboard的shake up非常大,排名波动几千名都存在的。笔者运气不错,是向上的shake:)。这里总结一下销量预测的基本流程。 从下图可以看到这次比

weixin_43901221的博客 5431

Linux下的实时流媒体(RTP)编程

流 媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下载边播放的方式,它是视频会议、IP电话等应用场合 的技术基础。RTP是进行实时流媒体传输的标准协议和关键技术,本文介绍如何在Linux下利用JRTPLIB进行实时流媒体编程。     一、流媒体简介         随着Internet的日益普及,在网络上传输的数据已经不再局限于文字和图形,而

武溪嵌人 2110

[TC3XX]AURIX TC3XX系列之启动流程

本文介绍了微控制器(MCU)启动过程中固件(Firmware)和启动软件(SSW)的工作原理。MCU上电复位后,硬件完成初始化,BootROM中的固件开始执行,进行参数加载、模式选择等操作。SSW作为第一个执行的软件,负责时钟配置、安全检查、多核管理及启动模式选择,最终跳转至用户代码。启动模式包括内部Flash启动、Bootloader模式(通过ASC或CAN接口)和备用启动模式(ABM),具体由复位类型、引脚配置和UCB设置决定。文章特别指出英飞凌TC3xx系列芯片中固件不可修改,只能通过配置参数定制启动

redparrot2008的博客 1420

【扫地机器人】详细介绍扫地机器人软硬件测试和场景化测试

本文提出2025版扫地机器人全生命周期测试方案,涵盖实验室仿真、硬件台架、客户实景等全流程验证。测试以"清洁率≥95%、覆盖率≥98%、MTBF≥1000h"为核心指标,采用数字孪生与120套真实场景结合的双V模型。重点包括:传感器精度(LDS误差<±10mm)、清洁系统性能(10g粉尘吸入率≥99%)、动力续航(800次循环容量保持≥80%)等硬件测试;以及SLAM重定位(误差<5cm)、AI识别(mAP>92%)等软件验证。方案特别针对宠物家庭(毛发缠绕率≤3%)、

2501_92897788的博客 2280

linux运行rtsp,Linux下的实时流媒体编程(RTP,RTCP,RTSP)2

RTP是目前解决流媒体实时传输问题的最好办法,如果需要在Linux平台上进行实时流媒体编程,可以考虑使用一些开放源代码的RTP库,如LIBRTP、JRTPLIB等。JRTPLIB是一个面向对象的RTP库,它完全遵循RFC1889设计,在很多场合下是一个非常不错的选择,下面就以JRTPLIB为例,讲述如何在Linux平台上运用RTP协议进行实时流媒体编程。3.1 环境搭建JRTPLIB 是一个用C+...

weixin_33309848的博客 631

机器学习教程 之 半监督学习 Co-training 协同训练 (论文、算法、数据集、代码)

这篇博客介绍的是一篇用于半监督分类问题的方法: 协同训练 Co-training, A. Blum and T. Mitchell, “Combining labeled and unlabeled data with co-training,” in Proc. of the 11th Annual Conf. on Computational Learning Theory, 1998.,这算是半监督领域里面始祖级的论文了,是1998年两位CMU大佬提出的方法。 之前还写过一篇关于Tri-trainin

冯良骏 的 博客 1万+

rtp协议 linux监控,在Linux平台上运用RTP协议进行实时流媒体编程 JRTPLIB

RTP是目前解决流媒体实时传输问题的最好办法,如果需要在Linux平台上进行实时流媒体编程,可以考虑使用一些开放源代码的RTP库,如LIBRTP、JRTPLIB等。JRTPLIB是一个面向对象的RTP库,它完全遵循RFC1889设计,在很多场合下是一个非常不错的选择,下面就以JRTPLIB为例,讲述如何在Linux平台上运用RTP协议进行实时流媒体编程。1 环境搭建JRTPLIB是一个用C++语言...

weixin_28814119的博客 423

【新华三】DHCP+TFTP+ZTP自动开局实战

设备运行ZTP功能,可以自动获取并自动加载开局文件,实现设备的免现场配置和部署,从而降低人力成本,提升部署效率。使用TFTP服务器工具进行文件的上传和下载,网上很多TFTP server软件,大家可以自行下载。3CDaemon等,可以根据使用自取所需。大家应该都了解ZTP,但是目前发现除了控制器之外仅使用ZTP开局的兄弟并不是很多,因此分享此过程方便大家批量开局,留出更多时间学习更多技术。电脑打开DHCP服务器,TFTP服务器,并通过网线连接到设备的管理口,若设备较多可以通过带外交换机等进行连接,

五大连池的镜子 4979

uniapp [全端兼容] - 实现上传本地视频到后端服务器及在线预览播放视频+移除视频+进度条上传,将已选视频上传服务端并可预览视频和删除功能,上传单个或多个视频文件及大文件(H5、小程序、app)

uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,uniapp+uview上传视频并预览,UNI-APP视频上传组件,实现视频文件上传视频回显,上传视频并预览、上传多个视频,实现上传视频功能+预览,上传显示视频功能,上传视频预览移除,批量上传视频,上传超大视频文件,视频上传并预览效果,uniapp上传视频,使用uview上传视频及预览,上传视频和删除视频功能,视频流上传播放功能,上传视频到后端,视频上传与实时预览功能,upload上传组件,视频播放器

🏆 前端领域优质创作者 1万+

ThinkPHP+Layui开发中小企业ERP系统实战指南

企业资源计划(ERP)系统是连接企业进销存、客户和员工权限的核心管理工具。在中小企业场景中,并发量有限但业务流程复杂,单体架构完全能够胜任。ThinkPHP作为成熟的PHP框架,提供ORM、事务和中间件支持,配合Layui这一无需前端工程化的UI框架,可快速构建数据录入、流程控制和报表展示等功能。该组合具备低开发成本、低维护门槛和高交付效率的优势,尤适合企业内部的后台管理系统。从数据库设计到服务层拆分,从弹窗交互到二级域名部署,这套方案已在真实项目中得到验证,为管理软件开发提供了一条稳定高效的路径。

weixin_33866037的博客 370

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Linux下的实时流媒体编程基础知识普及(RTP,RTCP,RTSP)

流媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下载边播放的方式,它是视频会议、IP电话等应用场合的技术基础。RTP是进行实时流媒体传输的标准协议和关键技术,本文介绍如何在Linux下利用JRTPLIB进行实时流媒体编程。 一、流媒体简介      随着Internet的日益普及,在网络上传输的数据已经不再局限于文字和图形,而是逐渐向声音和视频等

liwf616的专栏 1101

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

上一篇: QuickTime流媒体和Java
下一篇: 视音频、流媒体、图像编码标准综述
spring0317
博客等级 码龄19年 5粉丝 13原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值