直接贴代码, 这个class用于TS包的PCR计算
头文件
#ifndef _CPCR_H_
#define _CPCR_H_
#pragma once
/*
Title:PCR的计算
Author:kagula
Date:2019-3-1
Environment:
【1】Visual studio 2017 Community Update5
Desc:
用于S PES包中PCR,PTS字段的设置。
Feature:
[1]取当前时间并生成PCR
参考文档
【1】《TS科普25 TS音视频同步及PCR相关计算》
https://blog.csdn.net/cabbage2008/article/details/50281475
上文中从PCR逆推时间的公式是错误的.
[2]《ISO/IEC 13818-1》 TS标准 Page35
Specifically:
PCR_ base(i) = ((system_ clock_ frequency * t(i)) DIV 300) % 2^33 (2-1)
PCR_ ext(i) = ((system_ clock_ frequency * t(i)) DIV 1) % 300 (2-2)
PCR(i) = PCR_ base(i) * 300 + PCR_ ext(i) (2-3)
*/
#include <string>
namespace kagula
{
class CPCR
{
public:
CPCR(const unsigned short hour,
const unsigned short minute,
const double second);//时分秒转PCR
CPCR(const long long PCR);//PCR转时分秒
CPCR();//设置当前时间到时分秒,并转PCR
~CPCR();
unsigned short getHour() { return _hour; }
unsigned short getMinute() { return _minute; }
float getSecond() { return _second; }
unsigned long long getPCR_base() { return _PCR_base; }
unsigned long long getPCR_ext() { return _PCR_ext; }
unsigned long long getPCR() { return _PCR; }
std::string toString();
protected:
unsigned short _hour;
unsigned short _minute;
float _second;
unsigned long long _PCR_base;//33bits
unsigned long long _PCR_ext;//9bits
unsigned long long _PCR;//42bits
/*
《PES包的PTS详解》
https://blog.csdn.net/zm309442659/article/details/40298689
*/
void toPCR();
void fromPCR();
};
}
#endif
实现文件
#include "CPCR.h"
#include <chrono>
namespace kagula
{
CPCR::CPCR(const unsigned short hour,
const unsigned short minute,
const double second)
{
_hour = hour;
_minute = minute;
_second = second;
toPCR();
}
CPCR::CPCR(const long long PCR)
{
_PCR_base = PCR / 300;
_PCR_ext = PCR % 300;
fromPCR();
}
CPCR::CPCR()
{
[](unsigned short &_hour,
unsigned short &_minute,
float &_second) {
using namespace std::chrono;
auto time_now = system_clock::now();
auto duration_in_ms = duration_cast<milliseconds>(time_now.time_since_epoch());//从1970年开始
auto ms = duration_in_ms.count();//获取毫秒级时间戳 //https://www.epochconverter.com/
//auto milli = ms + 8 * 60 * 60 * 1000;//此处转化为东八区北京时间,如果是其它时区需要按需求修改
auto partial_ms = ms % 1000;//只取毫秒部份
auto tt = system_clock::to_time_t(time_now);
struct tm* ptm = localtime(&tt);
_hour = ptm->tm_hour;
_minute = ptm->tm_min;
_second = ptm->tm_sec + partial_ms / 1000.0;
}(_hour, _minute, _second);
toPCR();
}
CPCR::~CPCR()
{
}
void CPCR::toPCR()
{
double temp = ((_hour * 60) + _minute) * 60 + _second;
#ifdef _WIN32
_PCR_base = (unsigned long long((27000000 * temp) / 300)) & 0x1ffffffff;//2^33 //1<<33
_PCR_ext = unsigned long long((27000000 * temp) / 1) % 300;
#else
_PCR_base = (unsigned long long)((27000000 * temp) / 300) & 0x1ffffffff;//2^33 //1<<33
_PCR_ext = ((unsigned long long)(27000000 * temp) / 1) % 300l;
#endif
_PCR = _PCR_base * 300 + _PCR_ext;
}
void CPCR::fromPCR()
{
double t = _PCR / 27000000.0;
_hour = t / 3600;
_minute = (t - (_hour * 3600)) / 60;
_second = t - _minute * 60 - _hour * 3600;
}
std::string CPCR::toString()
{
char buf[64] = { 0 };
snprintf(buf, sizeof(buf), "%02d:%02d:%.3f", _hour, _minute, _second);
std::string str(buf);
return str;
}
}