h264检测是I帧还是P帧

转载请注明出处!

原文链接:http://blog.csdn.net/zgyulongfei/article/details/7558031


今天在网上找了一些资料,知道了如何检测h264中的帧类型,在这里记录下来。

首先,贴出nal单元类型定义(图从《新一代视频压缩编码标准H.264》摘录):



假设一段h264的码流为:00 00 00 01 41 E6 60……

其中的00 00 00 01为起始码,而起始码之后的下一个字节就可以检测出这一帧的类型。

在上面的码流中起始码之后的字节位 0x41,换算成二进制为 0100 0001。

注:我解读顺序为从左往右算。

(1)第1位禁止位,值为1表示语法出错

(2)第2~3位为参考级别

(3)第4~8为是nal单元类型,在此处为 0 0001换算成十进制为1。根据上图可知道这段码流是【不分区、非IDR图像的片】,在baseline的档次中就是P帧,因为baseline没有B帧。


如果是另一段码流:00 00 00 01 65 E8……

那么根据0x65字节(0110 0101)根据后5位换算十进制为5,也就是【IDR图像中的片】,即I帧。


用代码的方式可以这样写,int type = 0x65 & 0x1f,然后根据type在表中查找即可获得需要的结果。



  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
下面是一个简单的C代码示例,用于解析HEVC的NAL数据并确定其类型,包括I,P和B: ```c #include <stdio.h> #include <stdlib.h> #define NAL_TYPE_SLICE 1 #define NAL_TYPE_SLICE_DPA 2 #define NAL_TYPE_SLICE_DPB 3 #define NAL_TYPE_SLICE_DPC 4 #define NAL_TYPE_IDR 5 #define NAL_TYPE_SEI 6 #define NAL_TYPE_SPS 7 #define NAL_TYPE_PPS 8 #define NAL_TYPE_AUD 9 #define NAL_TYPE_EOSEQ 10 #define NAL_TYPE_EOSTREAM 11 #define NAL_TYPE_FILLER 12 int get_nal_type(unsigned char* nal_data) { return (nal_data[0] & 0x7E) >> 1; } int get_nal_unit_size(unsigned char* nal_data) { return (nal_data[0] << 24) | (nal_data[1] << 16) | (nal_data[2] << 8) | (nal_data[3]); } int is_I_frame(unsigned char* nal_data) { int nal_type = get_nal_type(nal_data); if (nal_type == NAL_TYPE_IDR) return 1; else if (nal_type == NAL_TYPE_SLICE) { int nal_ref_idc = nal_data[0] & 0x60; if (nal_ref_idc == 0x00) return 1; } return 0; } int is_B_frame(unsigned char* nal_data) { int nal_type = get_nal_type(nal_data); if (nal_type == NAL_TYPE_SLICE_DPB) return 1; return 0; } int is_P_frame(unsigned char* nal_data) { int nal_type = get_nal_type(nal_data); if (nal_type == NAL_TYPE_SLICE || nal_type == NAL_TYPE_SLICE_DPA || nal_type == NAL_TYPE_SLICE_DPC) { int nal_ref_idc = nal_data[0] & 0x60; if (nal_ref_idc == 0x40 || nal_ref_idc == 0x60) return 1; } return 0; } int main(int argc, char** argv) { if (argc < 2) { printf("Usage: %s filename\n", argv[0]); return -1; } FILE* fp = fopen(argv[1], "rb"); if (fp == NULL) { printf("Failed to open file %s\n", argv[1]); return -1; } unsigned char nal_data[1024]; while (!feof(fp)) { int nal_unit_size = 0; if (fread(&nal_unit_size, sizeof(int), 1, fp) == 0) break; nal_unit_size = get_nal_unit_size(nal_data); if (fread(nal_data, sizeof(unsigned char), nal_unit_size, fp) != nal_unit_size) break; int nal_type = get_nal_type(nal_data); if (is_I_frame(nal_data)) printf("NAL unit is I frame\n"); else if (is_P_frame(nal_data)) printf("NAL unit is P frame\n"); else if (is_B_frame(nal_data)) printf("NAL unit is B frame\n"); else printf("NAL unit is unknown frame type\n"); } fclose(fp); return 0; } ``` 该代码从文件中读取HEVC NAL数据,检测每个NAL单元的类型,并使用is_I_frame,is_P_frame和is_B_frame函数来确定类型。请注意,这只是一个简单的示例,对于更复杂的HEVC流,需要更复杂和严格的解析器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清缓

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值