得到RTP包中的timestamp

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

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

PTS,DTS的关系:

 http://www.cnblogs.com/qingquan/archive/2011/07/27/2118967.html

都知道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() << ":	Received " << 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() << ".	Presentation 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() << "	NPT: " << fSubsession.getNormalPlayTime(presentationTime);
25 //#endif
26     envir() << "
";
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 << "]07
";
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

原文地址:https://www.cnblogs.com/foohack/p/4791121.html