如何从RTP包的AP类型包,获取h265的PPS、SPS、VPS信息

ffmpeg播放rtp流,为了降低首开延迟,需要在SDP文件中指定PPS、SPS、VPS信息。抓包后发现wireshark无法解析AP包。需要自己进行AP包解析。RTP协议AP包格式如下:

根据如上信息,我们可以解析AP包,效果如下

  • 40 01,type=32,VPS(视频参数集)
  • 42 01,type=33,SPS(序列参数集)
  • 44 01,type=34,PPS(图像参数集)
  • 4E 01, type=39,SEI(补充增强信息)
  • 26 01,type=19,可能有RADL图像的IDR图像的SS编码数据 IDR
  • 02 01, type=01,被参考的后置图像,且非TSA、非STSA的SS编码数据
  • 46 01,type=35,分隔符,没用。

下图中红色部分是分隔符,橙色是VPS,黑色是SPS,黄色为PPS

SDP中的VPS等信息需要转换成base64。使用下面的函数可转换
#include <stdio.h>
#include <inttypes.h>
#include <math.h>
#include <limits.h>
#include <signal.h>
#include <stdint.h>
#include <string>
#include <string.h>
#include <iostream>


#define AV_BASE64_SIZE(x)  (((x)+2) / 3 * 4 + 1)
#   define AV_RB32(x)                                \
    (((uint32_t)((const uint8_t*)(x))[0] << 24) |    \
               (((const uint8_t*)(x))[1] << 16) |    \
               (((const uint8_t*)(x))[2] <<  8) |    \
                ((const uint8_t*)(x))[3])
using namespace std;
char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
{
    static const char b64[] =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    char *ret, *dst;
    unsigned i_bits = 0;
    int i_shift = 0;
    int bytes_remaining = in_size;

    if (in_size >= UINT_MAX / 4 ||
        out_size < AV_BASE64_SIZE(in_size))
        return NULL;
    ret = dst = out;
    while (bytes_remaining > 3) {
        i_bits = AV_RB32(in);
        in += 3; bytes_remaining -= 3;
        *dst++ = b64[ i_bits>>26        ];
        *dst++ = b64[(i_bits>>20) & 0x3F];
        *dst++ = b64[(i_bits>>14) & 0x3F];
        *dst++ = b64[(i_bits>>8 ) & 0x3F];
    }
    i_bits = 0;
    while (bytes_remaining) {
        i_bits = (i_bits << 8) + *in++;
        bytes_remaining--;
        i_shift += 8;
    }
    while (i_shift > 0) {
        *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
        i_shift -= 6;
    }
    while ((dst - ret) & 3)
        *dst++ = '=';
    *dst = '\0';

    return ret;
}

static int doLog = 0;
void hexDump(uint8_t* data,int len){
  if(doLog == 0)
    return;
  printf("[%d]",len);
  int pos = 0;
  uint8_t d = 0;
  while(pos<len){
    d = *(data+pos);
    printf("0x%02x,",(int)d);
    pos++;
  }
  printf("[%d]\n",len);
}
//sprop-vps=QAEMAf//AWAAAAMAkAAAAwAAAwBalZgJ; sprop-sps=QgEBAWAAAAMAkAAAAwAAAwBaoAeCAIh95ZWaSTK8BacIAAADAAgAAAMA8EA=; sprop-pps=RAHBcrRiQA==
//sprop-vps=DAH//wFgAAADALAAAAMAAAMAWqwJ; sprop-sps=AQFgAAADALAAAAMAAAMAWqAPCAPBY2uSRS9NQEBAQCA=; sprop-pps=wPLOcDs0
void getXPSfromAP(uint8_t* ap){
  int pos = 0;
  while(true){
    uint16_t hdr = (ap[pos+2]<<8)|(ap[pos+3]);
    int typ = (hdr>>9)&0x3f;
    int siz = (ap[pos+0]<<8)|(ap[pos+1])-2;
    switch(typ){
      case 32:
      { 
        char str_vps[100]={0};
        uint8_t* vps = (uint8_t*)malloc(siz);
        memcpy(vps,ap+pos+4,siz);
        av_base64_encode(str_vps,100,vps,siz);
        cout<<"sprop-vps="<<str_vps;
        hexDump(vps,siz);
        free(vps);
        break;
      }
      case 33:
      { 
        char str_sps[100]={0};
        uint8_t* sps = (uint8_t*)malloc(siz);
        memcpy(sps,ap+pos+4,siz);
        av_base64_encode(str_sps,100,sps,siz);
        cout<<"; sprop-sps="<<str_sps;
        hexDump(sps,siz);
        free(sps);
        break;
      }
      case 34:
      { 
        char str_pps[100]={0};
        uint8_t* pps = (uint8_t*)malloc(siz);
        memcpy(pps,ap+pos+4,siz);
        av_base64_encode(str_pps,100,pps,siz);
        cout<<"; sprop-pps="<<str_pps<<endl;
        hexDump(pps,siz);
        free(pps);
        return;
        break;
      }
      default:
        break;
    }
    pos += 4;
    pos += siz;
  }
}
int main(int argc, char *argv[]) {
  if(argc>=2){
    doLog = atoi(argv[1]);
  }
 
  uint8_t in[]={0x67, 0x42,0xc0,0x14,0xf4,0x0b,0x04,0xb4,0x20,0x00,0x00,0x03,0x00,0x20,0x00,0x00,0x03,0x03,0xd1,0xe2,0x85,0x54};
    char str_sps[100]={0};
    av_base64_encode(str_sps,100,in,22);
    cout<<"sps'sbasecode:"<<str_sps<<endl;
    uint8_t pps[]={0x68 ,0xce ,0x04 ,0xf2};
  char str_sps2[100]={0};
    av_base64_encode(str_sps2,100,pps,4);
    cout<<"pps'sbasecode:"<<str_sps2<<endl;
 
  uint8_t ap[] = {0x00,0x17,0x40,0x01,0x0c,0x01,0xff,0xff,0x01,0x60,0x00,0x00,0x03,0x00,0xb0,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x5a,0xac,0x09,0x00,0x22,0x42,
    0x01,0x01,0x01,0x60,0x00,0x00,0x03,0x00,0xb0,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x5a,0xa0,0x0f,0x08,0x03,0xc1,0x63,0x6b,0x92,0x45,0x2f,
    0x4d,0x40,0x40,0x40,0x40,0x20,0x00,0x08,0x44,0x01,0xc0,0xf2,0xce,0x70,0x3b,0x34,0x00,0x09,0x4e,0x01,0xe5,0x04,0x00,0x00,0x70,0x00,0x80,0x00,
    0x1e,0x4e,0x01,0x89,0x18,0x3a,0x98,0x75,0x30,0x1d,0x4c,0x0b,0xb8,0x7d,0x00,0x40,0x74,0x3d,0x13,0x40,0x42,0x00,0x00,0x04,0xb0,0x00,0x00,0x03,0x00,0xc8,0x80};
  getXPSfromAP(ap);
  return 0;
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/278324.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

共享单车之租赁需求预估

文章目录 第1关&#xff1a;数据探索与可视化第2关&#xff1a;特征工程第3关&#xff1a;租赁需求预估 第1关&#xff1a;数据探索与可视化 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 读取数据 数据探索与可视化 读取数据 数据保存在./step1/bike_train…

Intel FPGA 技术开放日

概要 时间&#xff1a;2023.11.14 全天 &#xff08; 9:00 - 16: 20&#xff09; 地点&#xff1a;北京望京. 凯悦酒店 主题内容&#xff1a;分享交流了Intel FPGA 产品技术优势和落地实践方案。 会议的议程 开场致词&#xff1a; FPGA业务&#xff0c;是几年前intel收购而…

四相八拍电机 --- linux驱动

四相八拍电机工作原理 四相八拍&#xff0c;也叫半步&#xff1a;AB—B—BC—C—CD—D—DA—A&#xff0c;再次从头循环。 四相:指步进电机中有四组线圈。 八拍:指的是四组线圈的通电时序。 步进电机:就是将电脉冲信号转变为角 位移或者线位移的开环控制电机&#xff08;即无…

Java网络编程---UDP

客户端 import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception {//1.创建客户端对象DatagramSocket socket new Datagra…

Grafana无法发送告警消息的飞书webhook(机器人)

1.问题描述 Grafana无法向飞书机器人发送报警消息&#xff0c;实测使用Grafana自带的webhook也不好使&#xff0c;对于用飞书办公的程序猿非常不便&#xff0c;后来发现一个报警神器&#xff0c;开源免费&#xff0c;关键是好用 PrometheusAlert 2.PrometheusAlert安装 Prom…

【leetcode】反转链表

/*** Definition for singly-linked list.* function ListNode(val, next) {* this.val (valundefined ? 0 : val)* this.next (nextundefined ? null : next)* }*/ /*** param {ListNode} head* return {ListNode}*/ var reverseList function(head) {if(headnul…

vue项目hdr格式文件放在assets下rgbeloader.load获取不到问题解决

如下图 我再App.vue组件中这样写 艾特符号定位 告诉系统 要src下的assets下的xhdr下的xidis.hdr 但是运行项目 他会告诉你找不到这个资源 我们改一下 我们组件时 App.vue 与assets同在 src目录下 用 ./去找 这样也是找不到的 我们需要将它放在静态资源包public下 public路…

【网络安全 | Misc】Training-Stegano-1

该题考察winhex工具使用 打开文件&#xff1a; 使用StegSolve并不能获取有效信息 使用winhex得到flag steganoI

什么是微服务架构以及落地思路

文章目录 前言一、各种架构的演进二、微服务架构落地思路 总结 前言 调用几个webapi就是微服务架构&#xff1f;或则是ngnixwebapi 集群就是微服务架构&#xff1f;这个文章带你弄懂微服务架构。 一、各种架构的演进 单体架构&#xff1a;放在一个服务器进程完成全部的后端处理…

Jackson进行Json反序列化对于一个小写字母开头后跟大写字母无法识别反序列成功问题

问题描述 json数据&#xff1a;{“pTargetId”:“123”} javaBean&#xff1a; Datapublic static class Test {private String pTargetId;}运行下面代码&#xff1a; public static void main(String[] args) throws JsonProcessingException {String json "{\"pT…

Echarts使用,Echarts图表自适应窗口大小

Echarts官方文档 1.下载Echarts 项目打打开终端直接通过命令 npm install echarts --save 下载完成后在项目package.json查看。 2.使用Echarts 引入方式有两种全局引入和局部引入 全局引入直接在项目main.js引入放到vue原型上。 import * as echarts from echarts Vue.pr…

基于EMD的滚动轴承故障诊断算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1EMD的基本原理 固有模态函数&#xff08;IMF&#xff09; 筛分过程 4.2 基于EMD的滚动轴承故障诊断算法 信号预处理 EMD分解 特征提取 故障诊断 5.算法完整程序工程 1.算法运行效…

【Web】Ctfshow Thinkphp5 非强制路由RCE漏洞

目录 非强制路由RCE漏洞 web579 web604 web605 web606 web607-610 前面审了一些tp3的sql注入,终于到tp5了&#xff0c;要说tp5那最经典的还得是rce 下面介绍非强制路由RCE漏洞 非强制路由RCE漏洞原理 非强制路由相当于开了一个大口子&#xff0c;可以任意调用当前框…

如何高效的在 Linux 环境下配置 yum 源?

作者&#xff1a;JackTian 来源&#xff1a;公众号「杰哥的IT之旅」 ID&#xff1a;Jake_Internet 链接&#xff1a;如何高效的在 Linux 环境下配置 yum 源&#xff1f; 方法一&#xff1a;使用脚本的方式创建本地 YUM 仓库 首先&#xff0c;脚本开始时检查光盘是否已经挂载。…

磁盘管理-------磁盘分区

目录 引导语&#xff1a; 一、磁盘分区概念及作用 二、磁盘分区 &#xff08;一&#xff09;添加磁盘 &#xff08;二&#xff09;创建分区 &#xff08;三&#xff09;创建文件系统 &#xff08;四&#xff09;挂载 &#xff08;五&#xff09;永久挂载 三、扩展分区…

Android画布Canvas drawPath绘制跟随手指移动的圆,Kotlin

Android画布Canvas drawPath绘制跟随手指移动的圆&#xff0c;Kotlin import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.os.Bundle import android.…

SSM驾校预约管理系统----计算机毕业设计

项目介绍 本项目分为管理员、教练、学员三种角色&#xff0c; 管理员角色包含以下功能&#xff1a; 学员管理、教练管理、车辆管理、关系管理、车辆维修管理、个人中心等功能。 教练角色包含以下功能&#xff1a; 我的课程、我的学员、车辆中心、个人中心等功能。 学员角色包…

《对话品牌》——数字化心理科学的变革

本期节目《对话品牌》栏目组邀请到了广东云有心理咨询有限公司董事长袁红萍女士参加栏目录制&#xff0c;分享其企业故事&#xff0c;树立品牌形象&#xff0c;提升品牌价值&#xff01; 节目嘉宾&#xff1a;袁红萍女士 节目主持人&#xff1a;董倩 节目播出平台&#xff1…

微生信 -- 0代码科研绘图,助力发高分文章

1&#xff0c;粘贴数据&#xff0c;一键出图 www.bioinformatics.com.cn微生信云平台以220多款在线绘图、分析模块为基础&#xff0c;致力于0代码在线分析数据&#xff0c;0代码在线绘制科研图片。让不会编写代码的科研工作者&#xff0c;贴贴数据&#xff0c;点点鼠标就能够进…

字节高级Java面试真题

今年IT寒冬&#xff0c;大厂都裁员或者准备裁员&#xff0c;作为开猿节流主要目标之一&#xff0c;我们更应该时刻保持竞争力。为了抱团取暖&#xff0c;林老师开通了《知识星球》&#xff0c;并邀请我阿里、快手、腾讯等的朋友加入&#xff0c;分享八股文、项目经验、管理经验…
最新文章