Здравствуйте, GloomyFriar, Вы писали:
GF>2. Анлизируя готовые MPEG-файлы, я заметил, что PTS есть не в каждом Pack'е. Почему?
PTS — Presentation Time Stamp, фактически метка синхронизации по времени для воспроизведения пачки. Заметь, что разница между значениями PTS соседних пачек — величина постоянная. Видно декодеру нужно производить синхронизацию через определённые промежутки времени.
GF>1. Каким образом вычисляются SCR, PTS и DTS?
GF>У меня есть уже закодированные фреймы, нужно записать их в файл.
GF>Структуру файла я знаю, для чего нужны SCR, PTS и DTS тоже более-менее понятно.
GF>Но вот как эти параметры вычислять, я не понимаю.
PTS и DTS вычисляются одинаково. Но у MPEG1 и MPEG2 разные заголовки пачки -> функции считывания тоже разные
Вот тебе структура заголовка пачки и системного заголовка у MPEG-2
http://files.rsdn.ru/48748/ps_big.jpg
я это делаю так :
/*
Считай, что buf содержит весь Pack Header
*/
double Mpeg1PackHeaderInfo::GetSCR()
{
BYTE highbit;
unsigned long low4Bytes;
double scr;
highbit = (buf[0] >> 3) & 0x01;
low4Bytes = ((buf[0] >> 1) & 0x03) << 30;
low4Bytes |= buf[1] << 22;
low4Bytes |= (buf[2] >> 1) << 15;
low4Bytes |= buf[3] << 7;
low4Bytes |= buf[4] >> 1;
double high_part = (double)((unsigned long)1 << 16);
unsigned long std_sys_clock_freq = 90000;
scr = (double)(highbit * high_part * high_part);
scr += (double)(low4Bytes);
scr /= (double)(std_sys_clock_freq);
return scr;
}
а PTS и DTS так
/*
buf тоже содержит с нулевого индекса полезные данные
bit.GetBitSequenceValue(BYTE byte, int start, int end)
берёт в байте указанный диапазон битов и из них делает число, например
start = 2
end = 4
byte =
1 0 1 1 0 1 1 0
0 1 2 3 4 5 6 7
=> полученное значение будет 1 1 0 или в десятичной 6
*/
double VideoParser::Parse_DTS_PTS()
{
int stamp;
double val;
stamp = bit.GetBitSequenceValue(buf[0], 4,6); // PTS(32..30)
stamp <<= 30;
stamp |= buf[1] << 22; // PTS(29..22)
stamp |= bit.GetBitSequenceValue(buf[2], 0,6) << 15; // PTS(21..15)
stamp |= buf[3] << 7; // PTS(14..7)
stamp |= bit.GetBitSequenceValue(buf[4], 0,6); // PTS(6..0)
val = static_cast<double>(stamp);
return val/90.0; // 90Khz clock
}