PCR的计算

直接贴代码,  这个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 

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 

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(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;
	}
}

 

 

你可能感兴趣的:(C++,图形图像视频)