2011-04-09 50 views
2

我想知道什么是开始代码以及如何在H 264编解码器中查找i帧。基本上,我试图使用Java加密视频文件,如果有人解释我如何解析视频,文件来获得使用Java的i帧?任何人都可以请回答。 感谢提前。什么是H 264编解码器中i帧的起始码?

+0

的可能重复[如何解码在Java环境中的H.264视频帧(http://stackoverflow.com/questions/2165593/how-to-decode-h-264-video-frame-in-java-环境) – 2011-04-09 07:30:20

回答

1

如果流为Annex-B格式,那么可以在NAL单元之后查找等于0x000001的“起始码前缀”。 NALU类型信息在第一个字节中提供。

3

上一个答案指的是nal_unit()中的nal_unit_type字段。 nal_unit的详细语法见ISO 14496-10的7.3.1节()。

H.264和MPEG 2的不同之处在于H.264区分了I切片和IDR。 I切片本身可以被解码成完整的图像,但是之后解码的切片有可能在I之前参考切片。第3.62节陈述“在解码IDR图像之后,解码顺序中的所有后续编码图像可以被解码来自在IDR图片之前解码的任何图片的预先解读“。这就像一个MPEG 2封闭的GOP。返回nal_unit_type,请参阅表7-1,它表明IDR具有nal_unit_type 5,但如果您要查找I切片,则可以查看access_unit_delimiter()中的primary_pic_type(表7-5)(其中,部分7.3.2.4),或者你可以检查slice_header的slice_type(表7-6)()(见第7.3.3节)

3

基于上述这里的评论是一个简单的代码片段,您可以使用:

ByteBuffer bb = ... // Byte buffer with your frame or h.264 NAL stream 

int marker = 0xffffffff; 
while (bb.hasRemaining()) { 
    int b = bb.get() & 0xff; 
    if (marker == 1) { 
     if ((b & 0x1f) == 5) 
      System.out.println("IDR slice!! " + (bb.position() - 1)); 
    } 
    marker = (marker << 8) | b; 
} 

如果你只是想知道一个给定的帧是否是一个IDR片(关键帧),你可以使用来自JCodec的H264Utils.idrSlice(http://jcodec.org):

ByteBuffer bb = ... // Byte buffer with your frame or h.264 NAL stream 
if(H264Utils.idrSlice(bb)) 
    System.out.println("IDR slice!!"); 

你想使用的库的原因是因为IDR NAL单元片不是在编码帧中携带的只有一片,所以你将不得不通过SPS,PPS和SEI的序列来获得,最终得到到您的IDR切片。

+0

我能找到的第一个正确答案:) – 2013-08-21 13:10:35