vlc源码分析流媒体的音视频同步

STN_LCD STN_LCD     2022-09-08     422

关键词:

http://www.cnblogs.com/jiayayao/p/6890882.html

 

    vlc播放流媒体时实现音视频同步,简单来说就是发送方发送的RTP包带有时间戳,接收方根据此时间戳不断校正本地时钟,播放音视频时根据本地时钟进行同步播放。首先了解两个概念:stream clock和system clock。stream clock是流时钟,可以理解为RTP包中的时间戳;system clock是本地时钟,可以理解为当前系统的Tick数。第一个RTP包到来时:

fSyncTimestamp = rtpTimestamp;// rtp时间戳赋值为本地记录的时间戳
fSyncTime = timeNow;// 本地同步时钟直接赋值为本地当前时钟,注意这样赋值是错误的,但随后就会被RTCP的SR包修正

    之后有RTP包到来,则根据上一次RTP包的时间戳差值计算得到真实的时间差值:

// Divide this by the timestamp frequency to get real time:
double timeDiff = timestampDiff/(double)timestampFrequency;// 差值除以90KHz得到真实时间

    当RTCP的Sender Report(SR)包到来时,会对fSyncTime进行重置,直接赋值为NTP时间戳

fSyncTime.tv_sec = ntpTimestampMSW - 0x83AA7E80; // 1/1/1900 -> 1/1/1970
double microseconds = (ntpTimestampLSW*15625.0)/0x04000000; // 10^6/2^32
fSyncTime.tv_usec = (unsigned)(microseconds+0.5);

    然后以此差值更新fSyncTime,也就是说live555接收部分的时钟fSyncTime既由RTP包时间戳不断的校正,也由RTCP的SR包不断的赋值修改。

    在RTSP的Session建立时会创建解码器的本地时钟,本地时钟是一对时钟,包括stream clock和system clock,初始值均为INVALID。

复制代码
static inline clock_point_t clock_point_Create( mtime_t i_stream, mtime_t i_system )
{
    clock_point_t p;

    p.i_stream = i_stream;// VLC_TS_INVALID
    p.i_system = i_system;// VLC_TS_INVALID

    return p;
}
复制代码

    当RTP数据到来的时候,不仅会更新VLC接收部分的时钟,VLC解码部分的时钟也会通过input_clock_Update()函数更新。当解码部分根据判定stream clock出现较大延迟时,还会重置本地时钟对,重置时设置system clock为当前本机时钟Tick数。live555接收到RTP数据后,存入BufferedPacket中。由于RTP封装H264是按照RFC3984来封装的,所以解析的时候按照该协议解析H264数据,解析时发现NALU起始,就会放入一个block_t中,然后该block_t就被推入以block_t为单位的数据fifo(src\misc\block.c)中,等待解码线程解码。block_t带有pts和dts,均为RTPSource的pts。

    解码时如果视频音频都有的话,会创建两个Decoder,每个Decoder包含一个fifo,同时会创建两个解码线程(视频和音频),分别从各自的fifo中取出数据解码。视频和音频解码入口都是DecoderThread,从fifo中取出数据数据进入视频或者音频的解码分支。视频解码线程在解码时会将block_t的pts和dts传递给AVPacket(modules/codec/avcodec/video.c):

pkt.pts = p_block->i_pts;
pkt.dts = p_block->i_dts;

    FFmpeg解码视频后,AVFrame将带有时间戳,但是这个时间戳是stream clock,之后会把stream clock转换为system clock,转换函数如下:

复制代码
static mtime_t ClockStreamToSystem( input_clock_t *cl, mtime_t i_stream )
{
    if( !cl->b_has_reference )
      return VLC_TS_INVALID;

    return ( i_stream - cl->ref.i_stream ) * cl->i_rate / INPUT_RATE_DEFAULT + cl->ref.i_system;
}
复制代码

    同理,音频解码完后,也会进行stream clock到system clock的转换。音频的解码后的数据会直接播放,视频解码完的图像帧会放入图像fifo(src\misc\picture_fifo.c)中,等待渲染线程渲染。渲染线程会根据解码后图像的显示时间,决定是否播放:

复制代码
            ......
decoded = picture_fifo_Pop(vout->p->decoder_fifo); if (is_late_dropped && decoded && !decoded->b_force) { const mtime_t predicted = mdate() + 0; /* TODO improve */ const mtime_t late = predicted - decoded->date; if (late > VOUT_DISPLAY_LATE_THRESHOLD) {// 延迟大于20ms,则不予播放,直接释放该图像 msg_Warn(vout, "picture is too late to be displayed (missing %d ms)", (int)(late/1000)); picture_Release(decoded); lost_count++; continue; } else if (late > 0) {// 延迟大于0小于20ms,打印日志并播放 msg_Dbg(vout, "picture might be displayed late (missing %d ms)", (int)(late/1000)); } }
......
复制代码

    整个接收流程的框图如下, 可以看出两个解码线程其实并没有直接联系,它们之间的联系是通过音视频数据包的的stream clock转换为system clock,然后渲染线程和声音播放线程根据本地时钟决定是否要播放当前音视频数据。

 

vlc源码分析播放流程

...后,vlc会执行一系列的流程。  首先需要了解视频以及流媒体处理及播放的流程,由链接中的描述,视频以及流媒体处理时,首先要解协议(http,rtmp,rtsp等),然后是解封装(mp4,mkv,avi等),获得音频码流和视频码流,分... 查看详情

vlc播放流程分析

...后,vlc会执行一系列的流程。  首先需要了解视频以及流媒体处理及播放的流程,由链接中的描述,视频以及流媒体处理时,首先要解协议(http,rtmp,rtsp等),然后是解封装(mp4,mkv,avi等),获得音频码流和视频码流,分... 查看详情

vlc源码分析调试学习hls协议

...bsp;   HTTPLiveStreaming(HLS)是苹果公司提出来的流媒体传输协议。与RTP协议不同的是,HLS可以穿透某些允许HTTP协议通过的防火墙。一、HLS播放模式(1) 点播模式(Videoondemand,VOD)    点播模式是指当前时... 查看详情

简单的多屏播放器示例(vlc+qt)

...播放器最多同时播放16个视频支持本地文件和rtsp、rtmp等流媒体播放VS2015工程,依赖Qt+VLC练手作品截图下载程序:download.csdn.net/detail/u014755412/9908787源码:github.com/FutaAlice/QtPlayer代码分析IMediaPlayer是为规定接口的基类提供了播放和... 查看详情

python-vlc 在启动之间切换播放媒体

...这里有额外的代码,只是为了计算每天的播放次数以进行分析 查看详情

vlc核心libvlc从源码下载工程建立实际使用一篇通

...bVLC关系  VLC属于VideoLAN开源项目组织中的一款全开源的流媒体服务器和多媒体播放器。作为流媒体服务器,VLC跨平台,支持多操作系统和计算机体系结构;作为多媒体播放器,VLC可以播放多种格式的媒体文件。... 查看详情

流媒体源流常见问题与延迟分析处理

...进行媒体格式的封装。为了适应网络传输,还要按照流媒体的相关标准协议,进行再次处理,最终得到输出流。播放就是将推流过程反过来,输入流经过流媒体协议解析,然后解封装,得到音频包(比... 查看详情

我如何使用 HTML 视频标签在 asp.net 应用程序中播放 VLC 实时流媒体视频

】我如何使用HTML视频标签在asp.net应用程序中播放VLC实时流媒体视频【英文标题】:howcaniplayVLClivestreamingvideoinasp.netapplicationusingHTMLvideoTag【发布时间】:2019-08-2215:16:08【问题描述】:我使用Http设置了VLC媒体播放器的实时流,我希... 查看详情

vlc源码分析调用openmax硬解码h.265

http://www.cnblogs.com/jiayayao/p/6964506.html   H.265(HEVC)编码格式能够在得到相同编码质量视频的前提下,使用相当于H.264(AVC)一半的存储容量,虽然H.265的算法复杂度比H.264高一个数量级,但是硬件水平在不断提高,因此H.265使用场... 查看详情

手机上的vlc怎么使用

...部分的主流视频格式。ios版本的VLC播放器视频来源:网络流媒体:对于普通用户来说,不适用且相当繁琐,必须输入视频详细网络ip地址才可以被识别出来。拓展资料VLC多媒体播放器(最初命名为VideoLAN客户端)是VideoLAN计划的多... 查看详情

anddroid使用vlc,录像截图功能,支持rtsprtmphttpsmb等等。流媒体,点播视频等等

上一篇写了ijkplayer的直播录像和截图功能,但是点播的时候录像不行,这里提别在写一个Demo,用的是VLC,实现直播或者视频点播,录像和截图!!!!包含视频格式和健壮性比ijklayer更好,... 查看详情

用vlc搭建rtsp流媒体服务器

...   在做视频传输客户端开发的时候,经常需要用到流媒体服务,VLC有着非常强大的流媒体处理能力,同时它也可以搭建流媒体服务器。VLC是一种开源的播放器,同时也可以用作流媒体服务器。vlc搭建rtsp流媒体服... 查看详情

anddroid使用vlc,录像截图功能,支持rtsprtmphttpsmb等等。流媒体,点播视频等等

...anddroid使用VLC,录像截图功能,支持rtsprtmphttpSMB等等。流媒体,点播视频等等下载Demo后,请直接搜索----VlcPlayerActivity------里面一看就会,不能再简单了,谢谢这个是Demo地址:MyUIFrame2021.rar-互联网文档类资源-CSDN下载 查看详情

ffmpeg之ffplay源码简要分析(代码片段)

1ffplay基本架构1.1视频解码播放的基本流程  ffmpeg视频解码播放的基本流程如下图所示:首先对网络媒体数据流进行解封装得到一般的视频封装格式比如MP4等,如果是本地播放的媒体文件就不需要解协议;然后对视... 查看详情

用vlc搭建rtsp流媒体服务器

...   在做视频传输客户端开发的时候,经常需要用到流媒体服务,VLC有着非常强大的流媒体处理能力,同时它也可以搭建流媒体服务器。VLC是一种开源的播放器,同时也可以用作流媒体服务器。vlc搭建rtsp流媒体服... 查看详情

darwinstreamserver源码分析

摘要 ?所谓的流式媒体简单的讲就是指人们通过网络实时的收看多媒体信息:如音频流、视频流等。与流式媒体对应的传统工作方式是下载+播放模式,即用户首先下载多媒体文件,然后再在本地播放,这种方法的一个主要缺... 查看详情

c/c++程序员的黄金发展方向:音视频开发

...实战ffmpegAPI精讲ffmpeg播放器ffmpeg转码器RTMP/RTSP/HLS/HTTP-FLV流媒体客户端开发SRS流媒体服务器源码分析WebRTC一对一通话WebRTC多人通话janusSFU(WebRTC)服务器源码分析2、音视频基础知识3、ffmpeg命令实战4、ffmpeg编程实战5、流媒体客户端实... 查看详情

音视频技术之ffplay源码分析-音视频同步(代码片段)

音视频同步的目的是为了使播放的声音和显示的画面保持一致。视频按帧播放,图像显示设备每次显示一帧画面,视频播放速度由帧率确定,帧率指示每秒显示多少帧;音频按采样点播放,声音播放设备每次... 查看详情