得到RTP包中的timestamp

NTP------网络时间协议

PTP------精确时间协议

都知道RTSP协议中,真正的数据传输是RTP协议来传输的,每个RTP包都有一个timestamp,(相对时间戳 relative timestamp)这个时间戳是需要经过换算的,我需要把它换算成相应的时间打印到播放器显示的每一帧上。

不过据http://stackoverflow.com/questions/20094998/retrieving-timestamp-in-rtp-rtsp

介绍,AftergettingFrame回调函数中处理的帧时间的,这个时间是PTS(presentationTime timestamp)

以下是代码片断:

 1 void DummySink::afterGettingFrame(void* clientData, unsigned frameSize, unsigned numTruncatedBytes,
 2 struct timeval presentationTime, unsigned durationInMicroseconds) {
 3     DummySink* sink = (DummySink*)clientData;
 4     sink->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
 5 }
 6
 7 // If you don‘t want to see debugging output for each received frame, then comment out the following line:
 8 #define DEBUG_PRINT_EACH_RECEIVED_FRAME 1
 9
10 void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
11 struct timeval presentationTime, unsigned /*durationInMicroseconds*/) {
12     // We‘ve just received a frame of data.  (Optionally) print out information about it:
13 #ifdef DEBUG_PRINT_EACH_RECEIVED_FRAME
14     if (fStreamId != NULL) envir() << "Stream \"" << fStreamId << "\"; ";
15     envir() << fSubsession.mediumName() << "/" << fSubsession.codecName() << ":\tReceived " << frameSize << " bytes";
16     if (numTruncatedBytes > 0) envir() << " (with " << numTruncatedBytes << " bytes truncated)";
17     char uSecsStr[6 + 1]; // used to output the ‘microseconds‘ part of the presentation time
18     sprintf_s(uSecsStr, "%06u", (unsigned)presentationTime.tv_usec);
19     envir() << ".\tPresentation time: " << (int)presentationTime.tv_sec << "." << uSecsStr;
20     if (fSubsession.rtpSource() != NULL && !fSubsession.rtpSource()->hasBeenSynchronizedUsingRTCP()) {
21         envir() << "!"; // mark the debugging output to indicate that this presentation time is not RTCP-synchronized
22     }
23 //#ifdef DEBUG_PRINT_NPT
24     envir() << "\tNPT: " << fSubsession.getNormalPlayTime(presentationTime);
25 //#endif
26     envir() << "\n";
27 #endif
28
29     // Then continue, to request the next frame of data:
30     continuePlaying();
31 }
32
33 Boolean DummySink::continuePlaying() {
34     if (fSource == NULL) return False; // sanity check (should not happen)
35
36     // Request the next frame of data from our input source.  "afterGettingFrame()" will get called later, when it arrives:
37     fSource->getNextFrame(fReceiveBuffer, DUMMY_SINK_RECEIVE_BUFFER_SIZE,
38         afterGettingFrame, this,
39         onSourceClosure, this);
40     return True;
41 }

以下是openRTSP Demo的timestamp片断:

1  if (notifyTheUser) {
2     struct timeval timeNow;
3     gettimeofday(&timeNow, NULL);
4     char timestampStr[100];
5     sprintf_s(timestampStr, "%ld%03ld", timeNow.tv_sec, (long)(timeNow.tv_usec/1000));
6     *env << (syncStreams ? "Synchronized d" : "D")
7         << "ata packets have begun arriving [" << timestampStr << "]\007\n";
8     return;
9   }

当然LIVE555自身就在服务端把PTS转换成RTP timestamp了然后进行传输,然后到客户端又自动将RTP timestamp转换成PTS。如果要把PTS转换成世界协调时间(UTS),就需要用gettimeofday()这个函数来转换。

references:

http://comments.gmane.org/gmane.comp.multimedia.live555.devel/12552

http://bbs.csdn.net/topics/390676557?page=1

http://live-devel.live.narkive.com/LfuvIyZj/rtp-timestamp-to-utc-time

时间: 2024-11-08 19:09:16

得到RTP包中的timestamp的相关文章

Live555中RTP包的打包与发送过程分析

这里主要分析一下,live555中关于RTP打包发送的部分.在处理完PLAY命令之后,就开始发送RTP数据包了(其实在发送PLAY命令的response包之前,就会发送一个RTP包,这里传输就已经开始了) 先介绍下主要的流程:RTP包的发送是从MediaSink::startPlaying函数调用开始的,在StartPlaying函数的最后会调用函数continuePlaying. continuePlaying函数是定义在MediaSink类中的纯虚函数,需要到特定媒体的sink子类中实现,对

RTP 包格式 详细解析

H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+      |0|1|2|3|4|5|6|7|      +-+-+-+-+-+-+-+-+      |F|NRI|  Type   |      +---------------+ F: 1 个比特.  forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0. NRI: 2 个比特.  nal_ref_idc

FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法

FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法 RFC3984是H.264的baseline码流在RTP方式下传输的规范,这里只讨论FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法. H.264的NAL层处理 H264以NALU(NALunit)为单位来支持编码数据在基于分组交换技术网络中传输. NALU定义了可用于基于分组和基于比特流系统的基本格式,同时给出头信息,从而提供了视频编码和外部事件的接口. H264编码过程中的三种不同的数据形式:S

RTP包的结构

live555中数据的发送最后是要使用RTP协议发送的,下面介绍一下RTP包格式. RTP packet RTP是基于UDP协议的,RTP服务器会通过UDP协议,通常每次会发送一个RTP packet.客户端通过解析RTP packet,读取其中的数据然后进行播放了. RTP packet的结构如下: RTP Header:RTP 包的头部 contributing sources:个数为0-n个,所以可以为空.具体定义参考rfc3550 RTP payload:即RTP要传输的数据 RTP H

JDK源码简析--java.lang包中的基础类库

题记 JDK,Java Development Kit. 我们必须先认识到,JDK只是,仅仅是一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含量来说,还是在一个层级上,它们都是需要被编译成字节码,在JRE中运行的,JDK编译后的结果就是jre/lib下得rt.jar,我们学习使用它的目的是加深对Java的理解,提高我们的Java编码水平. 本系列所有文章基于的JDK版本都是1.7.16. 本节内容 在本节中,简析java.lang包所包

java中常用的包、类、以及包中常用的类、方法、属性-----io包

由于最近有需要,所以下面是我整理的在开发中常用的包.类.以及包中常用的类.方法.属性:有需要的看看 java中常用的包.类.以及包中常用的类.方法.属性 常用的包 java.io.*; java.util.*; java.lang.*; java.math.*; java.sql.*; java.text.*; java.awt.*; javax.swing.*;   包名 接口 类 方法 属性 java.io.*; java.io.Serializable实现序列化 java.io.Buffe

地图包中和定位系统包中的主要类

地图包中的主要类: MapController :  主要控制地图移动,伸缩,以某个GPS坐标为中心,控制MapView中的view组件,管理Overlay,提供View的基本功能.使用多种地图模式(地图模式(某些城市可实时对交通状况进行更新),卫星模式,街景模式)来查看Google Map.常用方法:animateTo(GeoPoint point)  setCenter(GeoPoint point)  setZoom(int zoomLevel) 等. Mapview  : 是用来显示地图

黑马程序员——【Java基础】——File类、Properties集合、IO包中的其他类

---------- android培训.java培训.期待与您交流! ---------- 一.File类 (一)概述 1.File类:文件和目录路径名的抽象表现形式 2.作用: (1)用来将文件或文件夹封装成对象 (2)方便于对“文件”与“文件夹属性信息”进行操作 (3)File对象,可以作为参数传递给流的构造函数 (二)构造方法 * 通过File的构造函数创建File对象 方式1:File f = new File("c:\\a.txt"); 方式2:File f2 = newF

变量在SSIS包中的使用

2010~2011年经常使用SSIS包采集加工数据,后来换了工作就很少使用.最近又开始用那玩意采集数据,努力回想之前是怎样操作的,网上各种找各种纠结.趁这次使用记录下日常操作步骤,以备以后不时之需. --环境SQL Server2012.VS2010(安装数据库时默认会安装)下载示例数据库AdventureWorks2012 1 CREATE DATABASE [AdventureWorks2012] ON 2 (FILENAME=N'D:\SQL2012\MSSQL11.SQL12\MSSQL