mpeg-ps 视频流解析--psSystemHeader

37 阅读2分钟

写在前面

  • 依据mpeg-ps视频流格式,按文档逻辑对每个字段进行解析。
  • 这里给出 psSystemHeader的解析流程

PsSystemHeader.h

//
// Created by lzz on 2025/5/30.
//

#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);
    // todo 处理填充位的值
    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//PS_PARSER_PSSYSTEMHEADER_H

psSystemHeader.cpp

//
// Created by lzz on 2025/5/30.
//

#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);
    }
}