写在前面
- 依据mpeg-ps视频流格式,按文档逻辑对每个字段进行解析。
- 这里给出 psPackHeader的解析流程
psPackHeader 源码
psPackHeader.h
#ifndef PS_PARSER_PSPACKHEADER_H
#define PS_PARSER_PSPACKHEADER_H
#include <memory>
#include <iostream>
#include <unordered_map>
#define SCR_LEN 6
#define PROGRAM_MUX_RATE_LEN 3
#define PACK_STUFF_LEN 1
#define PREFIX_LEN 4
class PsPackHeader : public std::enable_shared_from_this<PsPackHeader>{
public:
explicit PsPackHeader(bool is_logging);
~PsPackHeader();
size_t input(const uint8_t* data, size_t len);
static size_t minLength();
private:
size_t parseSCR(const uint8_t* scr_start);
size_t parseStuffLen(const uint8_t* stuff);
size_t parseProgramMuxRate(const uint8_t* start);
size_t parseStuffingParam(const uint8_t* start);
void log();
std::unordered_map<std::string,std::string> paramMap;
bool is_logging_ = false;
size_t stuffing_length_ = 0;
};
#endif
psPackHeader.cpp
#include "PsPackHeader.h"
#include "LoggerStream.h"
#include "LogUtils.h"
PsPackHeader::PsPackHeader(bool is_logging) {
this->is_logging_ = is_logging;
paramMap.clear();
}
PsPackHeader::~PsPackHeader() {
LogInfo << "delete psPackHeader";
}
size_t PsPackHeader::input(const uint8_t *data, size_t len) {
if(len < minLength()){
return 0;
}
const uint8_t* ptr = data + PREFIX_LEN;
ptr += parseSCR(ptr);
ptr += parseProgramMuxRate(ptr);
ptr += parseStuffLen(ptr);
ptr += stuffing_length_;
log();
return ptr - data;
}
size_t PsPackHeader::minLength() {
return PREFIX_LEN + SCR_LEN + PROGRAM_MUX_RATE_LEN + PACK_STUFF_LEN;
}
size_t PsPackHeader::parseSCR(const uint8_t* scr_start){
uint64_t src_base = (uint64_t)(((scr_start[0] >> 3) & 0x07) << 30 ) |
(uint64_t)((scr_start[0] & 0x03 ) << 28 ) |
(uint64_t)(( scr_start[1] ) << 20) |
(uint64_t)(((scr_start[2] >> 3) & 0x1F ) << 15 ) |
(uint64_t)((scr_start[2] & 0x03 ) << 13 ) |
(uint64_t)(( scr_start[3] ) << 5) |
(uint64_t)((scr_start[4] >> 3) & 0x1F);
auto begin = (uint8_t)((scr_start[0] >> 6) & 0x03);
auto mark_bit_1 = (uint8_t)((scr_start[0] >> 2) & 0x01);
auto mark_bit_2 = (uint8_t)((scr_start[2] >> 2) & 0x01);
auto mark_bit_3 = (uint8_t)((scr_start[4] >> 2) & 0x01);
uint16_t scr_extension = (uint16_t)((scr_start[4] & 0x03) << 7) |
(uint16_t)((scr_start[5] >> 1)& 0x7F );
auto mark_bit_extension = (uint8_t)(scr_start[5] & 0x01);
LogUtils::addParam(paramMap,"src_base",src_base);
LogUtils::addParam(paramMap,"begin",begin);
LogUtils::addParam(paramMap,"mark_bit_1",mark_bit_1);
LogUtils::addParam(paramMap,"mark_bit_2",mark_bit_2);
LogUtils::addParam(paramMap,"mark_bit_3",mark_bit_3);
LogUtils::addParam(paramMap,"scr_extension",scr_extension);
LogUtils::addParam(paramMap,"mark_bit_extension",mark_bit_extension);
return SCR_LEN;
}
size_t PsPackHeader::parseProgramMuxRate(const uint8_t* start){
uint32_t program_mux_rate = (uint32_t)(start[0] << 14) |
(uint32_t)(start[1] << 6) |
(uint32_t)((start[2] >> 2) & 0x3F);
uint8_t mark = start[2] & 0x03;
LogUtils::addParam(paramMap,"program_mux_rate",program_mux_rate);
LogUtils::addParam(paramMap,"mark",mark);
return PROGRAM_MUX_RATE_LEN;
}
size_t PsPackHeader::parseStuffLen(const uint8_t *start) {
auto reserved = (uint8_t)(start[0] >> 3 & 0x1F);
auto pack_stuffing_length = start[0] & 0x07;
stuffing_length_ = static_cast<size_t>(pack_stuffing_length);
LogUtils::addParam(paramMap,"reserved",reserved);
LogUtils::addParam(paramMap,"pack_stuffing_length",pack_stuffing_length);
return PACK_STUFF_LEN;
}
size_t PsPackHeader::parseStuffingParam(const uint8_t *start) {
return 0;
}
void PsPackHeader::log(){
if(is_logging_){
LogUtils::printfParam(paramMap);
}
}