h264检测是I帧还是P帧,解决录像第一帧有马赛克问题

简介: 最近使用h264码流数据进行录像,但是录出来的第一帧有马赛克,究其原因是录像的第一帧不是关键帧,所以需要录像是需要判断第一帧是否是关键帧,方法有两种,第一种是原码流的基础上查找,第二种是将原码流传递给ffmpeg让ffmpeg判断key_frame,第二种相对简单,但是由于这样一来录像和解码视频切合...

最近使用h264码流数据进行录像,但是录出来的第一帧有马赛克,究其原因是录像的第一帧不是关键帧,所以需要录像是需要判断第一帧是否是关键帧,方法有两种,第一种是原码流的基础上查找,第二种是将原码流传递给ffmpeg让ffmpeg判断key_frame,第二种相对简单,但是由于这样一来录像和解码视频切合的太紧密,之后修改比较麻烦,所以选择第一种方案,查看注释1可以明白如何检测h264码流的关键帧,下面是我截取原码流的关键帧和p帧

 

0000000 :是sps

0000000  :  是pps

0000000  : 是帧类型

关键帧类型:

 

[cpp]  view plain copy
 
  1. <span style="color:#FF0000;"><span style="font-size:24px;">0000000: <span style="color:#CCCCCC;">0000 0001 6742 401f 9654 0501 ed00 f39e  ....gB@..T......  
  2. 0000010: a</span><span style="color:#3366FF;">000 0000 0168 ce38 80</span>00 0000 01<span style="color:#000000;">65</span> 8880  .....h.8.....e..  
  3. 0000020: 4001 8231 2000 4f11 d84d 5fff fb3b c28a  @..1 .O..M_..;..  
  4. 0000030: 00bc fc83 03db b3e3 8603 9c59 fa0f a82c  ...........Y...,  
  5. 0000040: df55 fdf6 8414 032a e766 bd4b fbea 05af  .U.....*.f.K....</span>  
  6. </span>  



 

P帧类型:

 

[cpp]  view plain copy
 
  1. 0000000: <span style="color:#C0C0C0;">0000 0001 6742 401f 9654 0501 ed00 f39e  ....gB@..T......  
  2. 0000010: a</span><span style="color:#3366FF;">000 0000 0168 ce38 80</span>00 0000 01<span style="color:#000000;">41</span> 9a02  .....h.8.....A..  
  3. 0000020: 0586 7cb9 9125 5788 8f90 7f1f 1930 7eef  ..|..%W......0~.  
  4. 0000030: 6383 bebd 2cc5 3627 92c3 390b 46dc d4a5  c...,.6'..9.F...  
  5. 0000040: 774b 3484 57f8 9840 fba3 1dd6 800f 2242  wK4.W..@......"B  
  6. 0000050: 8816 080f 8f8d 84c6 09aa cda6 363d 00da  ............6=..  
  7. 0000060: b563 4392 bc65 93e2 63bb 6d30 472e 3ef1  .cC..e..c.m0G.>.  
  8. 0000070: 545d 6a3f 36c3 2f7d 6b1e 3c91 d15d d687  T]j?6./}k.<..]..  


所以在代码中需要检索第29个字节,来判断是65还是41,

 

 

[python]  view plain copy
 
  1. public static String byteToHexString(byte src){     
  2.         StringBuilder stringBuilder = new StringBuilder("");     
  3.             int v = src & 0xFF;     
  4.             String hv = Integer.toHexString(v);    
  5.             if (hv.length() < 2) {     
  6.                 stringBuilder.append(0);   
  7.             }     
  8.             stringBuilder.append(hv);  
  9.         return stringBuilder.toString();     
  10.     }     
  11. private boolean isFirstIFrame = true;  
  12. private String IFrame = "65";//关键帧是0x65  
  13. //<span style="font-size:16px"></span>bArrayImage是存放h264原码流字节数组  
  14. if (是在录像) {  
  15.                 if (isFirstIFrame) {  
  16.                     String type = byteToHexString(bArrayImage[29]);  
  17.                     if (type.equals(IFrame)) {    //第29个字符是判断帧的类型  
  18.                         isFirstIFrame = false;  
  19.                         ShootingVideoData(bArrayImage, Video_Data_iVideoLen);//录制第一帧:关键帧  
  20.                     }  
  21.                 }else {  
  22.                     ShootingVideoData(bArrayImage, Video_Data_iVideoLen);  
  23.                 }  
  24.             }  

这样在录制出的第一帧录像就没有马赛克了。

 

注释1:检测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在表中查找即可获得需要的结果。

目录
相关文章
|
2月前
|
编解码 缓存 算法
视频帧里的I帧、P帧、B帧是什么?
I帧、P帧、B帧是视频编码中的基本概念。I帧是帧内编码帧,无需参考其他帧即可解码;P帧是前向预测编码帧,基于前一帧解码;B帧是双向预测编码帧,基于前后帧解码。IDR帧是一种特殊的I帧,用于即时解码刷新,防止错误传播。GOP(Group of Pictures)是一组连续的画面,第一个帧为I帧,gop_size设置越大,画质越好,但解码延迟增加。OpenGOP允许GOP间的帧依赖,而ClosedGOP则不允许。DTS(解码时间戳)和PTS(显示时间戳)分别用于解码和显示时间控制。
|
2月前
|
编解码 算法
为什么受损的视频数据通常显示为绿色?为什么很多30帧/秒的视频实际都是29.976帧/秒?
视频编码采用YUV格式因其亮度与色度分离,利于压缩且兼容黑白显示;受损视频常显绿色因YUV转RGB时Y、U、V为0导致;30帧/秒视频实为29.976帧/秒源于NTSC标准适应彩色电视需求;H.264等标准中H无特定含义,H.264又名MPEG-4 AVC,是ITU-T与ISO/IEC MPEG合作成果。
|
8月前
|
网络协议
计算机网络四种帧介绍,广播帧、未知帧、同网帧、异网帧
计算机网络四种帧介绍,广播帧、未知帧、同网帧、异网帧
|
8月前
|
存储 编解码 缓存
音视频基础: I帧 P帧 B帧 GOP DIR PTS DTS 帧率 码率的介绍
音视频基础: I帧 P帧 B帧 GOP DIR PTS DTS 帧率 码率的介绍
290 0
|
8月前
|
存储 编解码 算法
音视频学习之基础概念整理(rgb/yuv,pcm,采样频率,帧率,码率,i帧p帧b帧,dts/pts)
音视频学习之基础概念整理(rgb/yuv,pcm,采样频率,帧率,码率,i帧p帧b帧,dts/pts)
161 0
gstreamer向appsrc发送帧画面的代码
gstreamer向appsrc发送帧画面的代码
261 0
|
存储 SQL 数据库
从海康摄像机上读取RTSP视频流并存储当前帧到本地
从海康摄像机上读取RTSP视频流并存储当前帧到本地
2614 0
|
机器学习/深度学习 并行计算 算法
MMFlow :帧与帧之间的追光者
光流(Optical Flow),字面理解为“光的流动”,更准确的说法为:时变图像上的二维运动场,是视频数据的重要视觉线索,在动作识别、视频理解、视频分割、目标跟踪以及全景拼接等领域,都有广泛应用。
649 0
MMFlow :帧与帧之间的追光者
|
开发工具 Android开发 git
获取本地视频,网络视频的第一帧图片,并显示出来
获取本地视频,网络视频的第一帧图片,并显示出来
702 0
解码H264帧要注意的两个问题
解码H264帧要注意的两个问题
254 0

热门文章

最新文章

下一篇
开通oss服务