写在前面
- 依据mpeg-ps视频流格式,按文档逻辑对每个字段进行解析。
- 这里给出 psSystemHeader的解析流程
PsSystemHeader.h
#ifndef PS_PARSER_PSSYSTEMHEADER_H
#define PS_PARSER_PSSYSTEMHEADER_H
#include <iostream>
#include <memory>
#include <unordered_map>
#define PREFIX_LEN 4
#define HEADER_LEN 2
#define SH_PARAM_LEN 6
class PsSystemHeader : public std::enable_shared_from_this<PsSystemHeader>{
public:
explicit PsSystemHeader(bool is_logging);
~PsSystemHeader();
size_t input(const uint8_t* data,size_t len);
static size_t minLength();
private:
size_t parseHeaderLength(const uint8_t* start);
size_t parseParam(const uint8_t* start);
size_t parseStreamInfo(const uint8_t* start);
void log();
bool is_logging_;
size_t header_length_;
std::unordered_map<std::string,std::string> paramMap;
};
#endif
psSystemHeader.cpp
#include "PsSystemHeader.h"
#include "LoggerStream.h"
#include "LogUtils.h"
PsSystemHeader::PsSystemHeader(bool is_logging) {
this->is_logging_ = is_logging;
paramMap.clear();
}
PsSystemHeader::~PsSystemHeader() {
LogInfo << "delete psSystemHeader";
}
size_t PsSystemHeader::input(const uint8_t *data, size_t len) {
if(len < minLength()){
return 0;
}
const uint8_t* ptr = data + PREFIX_LEN;
ptr += parseHeaderLength(ptr);
ptr += parseParam(ptr);
log();
return PREFIX_LEN + HEADER_LEN + header_length_;
}
size_t PsSystemHeader::minLength() {
return PREFIX_LEN + HEADER_LEN + SH_PARAM_LEN;
}
size_t PsSystemHeader::parseHeaderLength(const uint8_t* start) {
auto header_length = (uint16_t)((start[0] << 8) | (start[1]));
this->header_length_ = static_cast<size_t>(header_length);
LogUtils::addParam(paramMap,"header_length",header_length);
return HEADER_LEN;
}
size_t PsSystemHeader::parseParam(const uint8_t* start){
auto marker_bit_1 = (uint8_t)((start[0] >> 7) & 0x01);
uint32_t rate_bound = (uint32_t)((start[0] & 0x7F) << 15) |
(start[1] << 7) | ((start[2] >> 1) &0x7F);
auto marker_bit_2 = (uint8_t)(start[2] & 0x01);
auto audio_bound = (uint8_t)((start[3] >> 2) & 0x3F);
auto fixed_flag = (uint8_t)((start[3] >> 1) & 0x01);
auto scps_flag = (uint8_t)(start[3] & 0x01);
auto system_audio_lock_flag = (uint8_t)((start[4] >> 7) & 0x01);
auto system_video_lock_flag = (uint8_t)((start[4] >> 6) & 0x01);
auto marker_bit_3 = (uint8_t)((start[4] >> 5) & 0x01);
auto video_bound = (uint8_t)(start[4] & 0x1F);
auto packet_rate_restriction_flag = (uint8_t)((start[5] >> 7) & 0x01);
auto reserved_bits = (uint8_t)(start[5] & 0x7F);
LogUtils::addParam(paramMap,"marker_bit_1",marker_bit_1);
LogUtils::addParam(paramMap, "rate_bound", rate_bound);
LogUtils::addParam(paramMap,"marker_bit_2",marker_bit_2);
LogUtils::addParam(paramMap, "audio_bound", audio_bound);
LogUtils::addParam(paramMap, "fixed_flag", fixed_flag);
LogUtils::addParam(paramMap, "scps_flag", scps_flag);
LogUtils::addParam(paramMap, "system_audio_lock_flag", system_audio_lock_flag);
LogUtils::addParam(paramMap, "system_video_lock_flag", system_video_lock_flag);
LogUtils::addParam(paramMap,"marker_bit_3",marker_bit_3);
LogUtils::addParam(paramMap, "video_bound", video_bound);
LogUtils::addParam(paramMap, "packet_rate_restriction_flag", packet_rate_restriction_flag);
LogUtils::addParam(paramMap, "reserved_bits", reserved_bits);
return SH_PARAM_LEN;
}
size_t PsSystemHeader::parseStreamInfo(const uint8_t *start) {
return 0;
}
void PsSystemHeader::log(){
if(is_logging_){
LogUtils::printfParam(paramMap);
}
}