视频编解码学习(2):H264学习笔记

RT


文章1:最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)

http://blog.csdn.net/leixiaohua1020/article/details/38868499

文章2:最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)

http://blog.csdn.net/leixiaohua1020/article/details/42181571


现在把我学习的重要内容总结一下:


在文章1里面,有一段代码:

int iFrameIndex = 1;
    while( av_read_frame(pFormatCtx, packet) >= 0 ) {
        m_mylog.LogFile(_T("Frame: %d, Size: %d"), iFrameIndex ++, packet->size);
        
        if( packet->stream_index == videoindex ) {
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
            if( ret < 0 ) {
                printf("Decode Error.\n");
                return -1;
            }
        }
    }
这里会计算该文件有多少个Frame,我测试的结果为250,但这里仅贴出前10个Frame的结果。

DEBUG - Frame: 1, Size: 22572
DEBUG - Frame: 2, Size: 2803
DEBUG - Frame: 3, Size: 623
DEBUG - Frame: 4, Size: 495
DEBUG - Frame: 5, Size: 3730
DEBUG - Frame: 6, Size: 699
DEBUG - Frame: 7, Size: 635
DEBUG - Frame: 8, Size: 4056
DEBUG - Frame: 9, Size: 552
DEBUG - Frame: 10, Size: 613


同理在文章2里面,有一段代码:

    while( 1 ) {
        // 
        cur_size = fread(in_buffer, 1, IN_BUFFER_SIZE, fp_in);
        if( cur_size == 0 ) {
            break;
        }
        cur_ptr = in_buffer;
        
        while( cur_size > 0 ) {
            // 解析获得一个Packet
            int len = av_parser_parse2(
                pCodecParserCtx, pCodecCtx,
                &packet.data, &packet.size,
                cur_ptr , cur_size ,
                AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
            
            cur_ptr += len;
            cur_size -= len;
            
            if( packet.size == 0 ) {
                continue;
            }
            
            // decode this buffer
            //Some Info from AVCodecParserContext
            m_mylog.LogFile(_T("Index: %d Packet Size:%6d"), iPacketIndex ++, packet.size);

            // ...
        }
也是获取有多少个Frame的,不过使用的方法不一样。但是结果是相同的。



// 2015/7/22今天我好好的调试了一个h264文件,想要探索它究竟是什么?当然了,不可避免的需要学习新知识。

先给出几个自问自答。

1. h264是什么?

新一代高清视频编码格式

2. NALU是什么?

答:NALU头结构:NALU类型(5bit)、重要性指示位(2bit)、禁止位(1bit)

因为NALU在文件里面是二进制的,为了区分这些NALU,需要定义(0x00000001或者0x000001)来作为间隔符。

区别:如果NALU对应的Slice(Slice为P帧,也就是差别帧)为一帧的开始,则用4字节表示,即0x00000001;否则用3字节表示,0x000001。


参考:http://blog.csdn.net/wudebao5220150/article/details/13810671


3.如何解析h264 ?

为了解析h264,我先上传一个 h264的文件ds.h264

该文件大小为:201,432 字节

3.1 使用ffmpeg解析h264文件

参考:http://blog.csdn.net/leixiaohua1020/article/details/38868499

首先使用FFMPEG里面的av_read_frame读取所有的帧,得到如下结果:
Frame: 1, Size: 9777
Frame: 2, Size: 215
Frame: 3, Size: 113
Frame: 4, Size: 75
Frame: 5, Size: 95
Frame: 6, Size: 435
Frame: 7, Size: 217
Frame: 8, Size: 123
Frame: 9, Size: 139
Frame: 10, Size: 913
Frame: 11, Size: 291
Frame: 12, Size: 182
Frame: 13, Size: 184
Frame: 14, Size: 10118
Frame: 15, Size: 1017
Frame: 16, Size: 260
Frame: 17, Size: 235
Frame: 18, Size: 2773
Frame: 19, Size: 509
Frame: 20, Size: 340
Frame: 21, Size: 361
Frame: 22, Size: 5374
Frame: 23, Size: 841
Frame: 24, Size: 608
Frame: 25, Size: 363
Frame: 26, Size: 5233
Frame: 27, Size: 1143
Frame: 28, Size: 677
Frame: 29, Size: 486
Frame: 30, Size: 4918
Frame: 31, Size: 1330
Frame: 32, Size: 659
Frame: 33, Size: 591
Frame: 34, Size: 4944
Frame: 35, Size: 1745
Frame: 36, Size: 777
Frame: 37, Size: 923
Frame: 38, Size: 5555
Frame: 39, Size: 1930
Frame: 40, Size: 1037
Frame: 41, Size: 1093
Frame: 42, Size: 5735
Frame: 43, Size: 2351
Frame: 44, Size: 1296
Frame: 45, Size: 1246
Frame: 46, Size: 5268
Frame: 47, Size: 2193
Frame: 48, Size: 1142
Frame: 49, Size: 1006
Frame: 50, Size: 4657
Frame: 51, Size: 2039
Frame: 52, Size: 919
Frame: 53, Size: 950
Frame: 54, Size: 5293
Frame: 55, Size: 2063
Frame: 56, Size: 799
Frame: 57, Size: 862
Frame: 58, Size: 5294
Frame: 59, Size: 1743
Frame: 60, Size: 1136
Frame: 61, Size: 890
Frame: 62, Size: 5284
Frame: 63, Size: 1902
Frame: 64, Size: 920
Frame: 65, Size: 962
Frame: 66, Size: 5593
Frame: 67, Size: 2280
Frame: 68, Size: 1087
Frame: 69, Size: 907
Frame: 70, Size: 5525
Frame: 71, Size: 2117
Frame: 72, Size: 976
Frame: 73, Size: 1202
Frame: 74, Size: 5578
Frame: 75, Size: 2170
Frame: 76, Size: 981
Frame: 77, Size: 951
Frame: 78, Size: 5468
Frame: 79, Size: 1555
Frame: 80, Size: 1009
Frame: 81, Size: 710
Frame: 82, Size: 5009
Frame: 83, Size: 1361
Frame: 84, Size: 691
Frame: 85, Size: 638
Frame: 86, Size: 4953
Frame: 87, Size: 1514
Frame: 88, Size: 607
Frame: 89, Size: 778
Frame: 90, Size: 4590
Frame: 91, Size: 1390
Frame: 92, Size: 607
Frame: 93, Size: 526
Frame: 94, Size: 4905
Frame: 95, Size: 1282
Frame: 96, Size: 651
Frame: 97, Size: 654
Frame: 98, Size: 5477
Frame: 99, Size: 2072
Frame: 100, Size: 1069

Total Frame Size: 201432
看到没有,正好是201432,这样一看,一共有100帧。但是还有其他问题,哪些是I帧,哪些是P帧?如何将这些帧通过RTP发送出去呢?这些帧在二进制的格式是什么?好,别急,现在只是FFMPEGE帮助我解析了这些帧,当然文件h264文件在手,我也可以自己解析这些帧。



3.2 全手工解析h264文件

参考:http://download.csdn.net/download/yechuanfei/4313339
将该文章里面的代码下载后,并仔细调试,我得到如下结果:
Index: 1 -- len: 24 	-- prefix: 4 	nal_unit_type: 7
Index: 2 -- len: 5 	-- prefix: 4 	nal_unit_type: 8
Index: 3 -- len: 698 	-- prefix: 3 	nal_unit_type: 6
Index: 4 -- len: 9036 	-- prefix: 3 	nal_unit_type: 5
Index: 5 -- len: 211 	-- prefix: 4 	nal_unit_type: 1
Index: 6 -- len: 109 	-- prefix: 4 	nal_unit_type: 1
Index: 7 -- len: 71 	-- prefix: 4 	nal_unit_type: 1
Index: 8 -- len: 91 	-- prefix: 4 	nal_unit_type: 1
Index: 9 -- len: 431 	-- prefix: 4 	nal_unit_type: 1
Index: 10 -- len: 213 	-- prefix: 4 	nal_unit_type: 1
Index: 11 -- len: 119 	-- prefix: 4 	nal_unit_type: 1
Index: 12 -- len: 135 	-- prefix: 4 	nal_unit_type: 1
Index: 13 -- len: 909 	-- prefix: 4 	nal_unit_type: 1
Index: 14 -- len: 287 	-- prefix: 4 	nal_unit_type: 1
Index: 15 -- len: 178 	-- prefix: 4 	nal_unit_type: 1
Index: 16 -- len: 180 	-- prefix: 4 	nal_unit_type: 1
Index: 17 -- len: 10114 -- prefix: 4 	nal_unit_type: 1
Index: 18 -- len: 1013 	-- prefix: 4 	nal_unit_type: 1
Index: 19 -- len: 256 	-- prefix: 4 	nal_unit_type: 1
Index: 20 -- len: 231 	-- prefix: 4 	nal_unit_type: 1
Index: 21 -- len: 2769 	-- prefix: 4 	nal_unit_type: 1
Index: 22 -- len: 505 	-- prefix: 4 	nal_unit_type: 1
Index: 23 -- len: 336 	-- prefix: 4 	nal_unit_type: 1
Index: 24 -- len: 357 	-- prefix: 4 	nal_unit_type: 1
Index: 25 -- len: 5370 	-- prefix: 4 	nal_unit_type: 1
Index: 26 -- len: 837 	-- prefix: 4 	nal_unit_type: 1
Index: 27 -- len: 604 	-- prefix: 4 	nal_unit_type: 1
Index: 28 -- len: 359 	-- prefix: 4 	nal_unit_type: 1
Index: 29 -- len: 5229 	-- prefix: 4 	nal_unit_type: 1
Index: 30 -- len: 1139 	-- prefix: 4 	nal_unit_type: 1
Index: 31 -- len: 673 	-- prefix: 4 	nal_unit_type: 1
Index: 32 -- len: 482 	-- prefix: 4 	nal_unit_type: 1
Index: 33 -- len: 4914 	-- prefix: 4 	nal_unit_type: 1
Index: 34 -- len: 1326 	-- prefix: 4 	nal_unit_type: 1
Index: 35 -- len: 655 	-- prefix: 4 	nal_unit_type: 1
Index: 36 -- len: 587 	-- prefix: 4 	nal_unit_type: 1
Index: 37 -- len: 4940 	-- prefix: 4 	nal_unit_type: 1
Index: 38 -- len: 1741 	-- prefix: 4 	nal_unit_type: 1
Index: 39 -- len: 773 	-- prefix: 4 	nal_unit_type: 1
Index: 40 -- len: 919 	-- prefix: 4 	nal_unit_type: 1
Index: 41 -- len: 5551 	-- prefix: 4 	nal_unit_type: 1
Index: 42 -- len: 1926 	-- prefix: 4 	nal_unit_type: 1
Index: 43 -- len: 1033 	-- prefix: 4 	nal_unit_type: 1
Index: 44 -- len: 1089 	-- prefix: 4 	nal_unit_type: 1
Index: 45 -- len: 5731 	-- prefix: 4 	nal_unit_type: 1
Index: 46 -- len: 2347 	-- prefix: 4 	nal_unit_type: 1
Index: 47 -- len: 1292 	-- prefix: 4 	nal_unit_type: 1
Index: 48 -- len: 1242 	-- prefix: 4 	nal_unit_type: 1
Index: 49 -- len: 5264 	-- prefix: 4 	nal_unit_type: 1
Index: 50 -- len: 2189 	-- prefix: 4 	nal_unit_type: 1
Index: 51 -- len: 1138 	-- prefix: 4 	nal_unit_type: 1
Index: 52 -- len: 1002 	-- prefix: 4 	nal_unit_type: 1
Index: 53 -- len: 4653 	-- prefix: 4 	nal_unit_type: 1
Index: 54 -- len: 2035 	-- prefix: 4 	nal_unit_type: 1
Index: 55 -- len: 915 	-- prefix: 4 	nal_unit_type: 1
Index: 56 -- len: 946 	-- prefix: 4 	nal_unit_type: 1
Index: 57 -- len: 5289 	-- prefix: 4 	nal_unit_type: 1
Index: 58 -- len: 2059 	-- prefix: 4 	nal_unit_type: 1
Index: 59 -- len: 795 	-- prefix: 4 	nal_unit_type: 1
Index: 60 -- len: 858 	-- prefix: 4 	nal_unit_type: 1
Index: 61 -- len: 5290 	-- prefix: 4 	nal_unit_type: 1
Index: 62 -- len: 1739 	-- prefix: 4 	nal_unit_type: 1
Index: 63 -- len: 1132 	-- prefix: 4 	nal_unit_type: 1
Index: 64 -- len: 886 	-- prefix: 4 	nal_unit_type: 1
Index: 65 -- len: 5280 	-- prefix: 4 	nal_unit_type: 1
Index: 66 -- len: 1898 	-- prefix: 4 	nal_unit_type: 1
Index: 67 -- len: 916 	-- prefix: 4 	nal_unit_type: 1
Index: 68 -- len: 958 	-- prefix: 4 	nal_unit_type: 1
Index: 69 -- len: 5589 	-- prefix: 4 	nal_unit_type: 1
Index: 70 -- len: 2276 	-- prefix: 4 	nal_unit_type: 1
Index: 71 -- len: 1083 	-- prefix: 4 	nal_unit_type: 1
Index: 72 -- len: 903 	-- prefix: 4 	nal_unit_type: 1
Index: 73 -- len: 5521 	-- prefix: 4 	nal_unit_type: 1
Index: 74 -- len: 2113 	-- prefix: 4 	nal_unit_type: 1
Index: 75 -- len: 972 	-- prefix: 4 	nal_unit_type: 1
Index: 76 -- len: 1198 	-- prefix: 4 	nal_unit_type: 1
Index: 77 -- len: 5574 	-- prefix: 4 	nal_unit_type: 1
Index: 78 -- len: 2166 	-- prefix: 4 	nal_unit_type: 1
Index: 79 -- len: 977 	-- prefix: 4 	nal_unit_type: 1
Index: 80 -- len: 947 	-- prefix: 4 	nal_unit_type: 1
Index: 81 -- len: 5464 	-- prefix: 4 	nal_unit_type: 1
Index: 82 -- len: 1551 	-- prefix: 4 	nal_unit_type: 1
Index: 83 -- len: 1005 	-- prefix: 4 	nal_unit_type: 1
Index: 84 -- len: 706 	-- prefix: 4 	nal_unit_type: 1
Index: 85 -- len: 5005 	-- prefix: 4 	nal_unit_type: 1
Index: 86 -- len: 1357 	-- prefix: 4 	nal_unit_type: 1
Index: 87 -- len: 687 	-- prefix: 4 	nal_unit_type: 1
Index: 88 -- len: 634 	-- prefix: 4 	nal_unit_type: 1
Index: 89 -- len: 4949 	-- prefix: 4 	nal_unit_type: 1
Index: 90 -- len: 1510 	-- prefix: 4 	nal_unit_type: 1
Index: 91 -- len: 603 	-- prefix: 4 	nal_unit_type: 1
Index: 92 -- len: 774 	-- prefix: 4 	nal_unit_type: 1
Index: 93 -- len: 4586 	-- prefix: 4 	nal_unit_type: 1
Index: 94 -- len: 1386 	-- prefix: 4 	nal_unit_type: 1
Index: 95 -- len: 603 	-- prefix: 4 	nal_unit_type: 1
Index: 96 -- len: 522 	-- prefix: 4 	nal_unit_type: 1
Index: 97 -- len: 4901 	-- prefix: 4 	nal_unit_type: 1
Index: 98 -- len: 1278 	-- prefix: 4 	nal_unit_type: 1
Index: 99 -- len: 647 	-- prefix: 4 	nal_unit_type: 1
Index: 100 -- len: 650 	-- prefix: 4 	nal_unit_type: 1
Index: 101 -- len: 5473 -- prefix: 4 	nal_unit_type: 1
Index: 102 -- len: 2068 -- prefix: 4 	nal_unit_type: 1
Index: 103 -- len: 1065 -- prefix: 4 	nal_unit_type: 1
Total is : 201432
看到没,恰好也是201432个字节。
这里的 prefix为4表明其值为0x00000001,prefix为3表明其值为0x000001。

nal_unit_type的含义见如下结构体:
//H264定义的类型 values for nal_unit_type
typedef enum {
    NALU_TYPE_SLICE     = 1, //P 帧
    NALU_TYPE_DPA      = 2,
    NALU_TYPE_DPB      = 3,
    NALU_TYPE_DPC      = 4,
    NALU_TYPE_IDR      = 5, // I帧
    NALU_TYPE_SEI      = 6, // 补充增强信息
    NALU_TYPE_SPS      = 7, // 序列参数集Sequence Parameter Set
    NALU_TYPE_PPS      = 8, // 图像参数集Picture Parameter Set
    NALU_TYPE_AUD      = 9,
    NALU_TYPE_EOSEQ     = 10,
    NALU_TYPE_EOSTREAM    = 11,
    NALU_TYPE_FILL      = 12,
#if (MVC_EXTENSION_ENABLE)
    NALU_TYPE_PREFIX    = 14,
    NALU_TYPE_SUB_SPS   = 15,
    NALU_TYPE_SLC_EXT   = 20,
    NALU_TYPE_VDRD     = 24  // View and Dependency Representation Delimiter NAL Unit
#endif
} NaluType;
具体的对比一下就可以知道了。


ffmpeg解析的帧 & 全手工解析的帧

对于第一个关键帧而言:


ffmpeg解析全手工解析
Frame: 1, Size: 9777
Index: 1 -- len: 24 	-- prefix: 4 	nal_unit_type: 7
Index: 2 -- len: 5 	-- prefix: 4 	nal_unit_type: 8
Index: 3 -- len: 698 	-- prefix: 3 	nal_unit_type: 6
Index: 4 -- len: 9036 	-- prefix: 3 	nal_unit_type: 5
<pre name="code" class="cpp">Frame: 100, Size: 1069
 
Index: 103 -- len: 1065 -- prefix: 4 	nal_unit_type: 1

ffmpeg解析的一个帧包含的信息可不少,包括7(序列参数集), 8(图像参数集), 6(补充增强信息), 5(I帧,即关键帧)的内容以及他们的前缀(即NALU的间隔)长。
而其他的帧就是P帧了,同样的ffmepg解析的帧 等于 真实的帧内容加上 NALU的间隔。

播放该h264文件

a. 新建一个w.sdp文件,内容如下:
m=video 5234 RTP/AVP 96
a=rtpmap:96 H264
a=framerate:25
c=IN IP4 172.30.191.2
172.30.191.2是流媒体播放器接收的地址,5234是RTP接收流媒体的端口

b. 执行ffplay.exe w.sdp 或者 VLC media player打开w.sdp均可以

c. 使用3.2参考中下载的代码播放就可以了








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
h.264视频编解码源代码.rar 详细说明:h.264标准代码,用于视频编码!可以实现各种视频的编码和解码,可以在这个代码的基础上进行各种开发,比如算法的优化,转码技术,实现各种分辨了的转码-h.264 standard code, uses in the video frequency code! May realize each kind of video frequency code and the decoding, may carry on each kind of development in this code foundation, for instance the algorithm optimization, transfers the code technology, realizes each kind has distinguished extension code 文件列表: jm73 ....\JM ....\..\bin ....\..\...\decoder.cfg ....\..\...\encoder.cfg ....\..\...\lencod.exe ....\..\...\lencod.map ....\..\...\lencod.pdb ....\..\CHANGES.TXT ....\..\Changes_detail.txt ....\..\copyright.txt ....\..\disclaimer.txt ....\..\doc ....\..\...\coding_style.doc ....\..\...\doxygen.txt ....\..\...\h26l.css ....\..\...\ldecod.dox ....\..\...\lencod.dox ....\..\encoder.cfg ....\..\foreman_part_qcif.yuv ....\..\ldecod ....\..\......\inc ....\..\......\...\annexb.h ....\..\......\...\biaridecod.h ....\..\......\...\block.h ....\..\......\...\cabac.h ....\..\......\...\context_ini.h ....\..\......\...\contributors.h ....\..\......\...\ctx_tables.h ....\..\......\...\defines.h ....\..\......\...\elements.h ....\..\......\...\erc_api.h ....\..\......\...\erc_do.h ....\..\......\...\erc_globals.h ....\..\......\...\errorconcealment.h ....\..\......\...\fmo.h ....\..\......\...\global.h ....\..\......\...\header.h ....\..\......\...\image.h ....\..\......\...\leaky_bucket.h ....\..\......\...\macroblock.h ....\..\......\...\mbuffer.h ....\..\......\...\mb_access.h ....\..\......\...\memalloc.h ....\..\......\...\nalu.h ....\..\......\...\nalucommon.h ....\..\......\...\output.h ....\..\......\...\parset.h ....\..\......\...\parsetcommon.h ....\..\......\...\rtp.h ....\..\......\...\sei.h ....\..\......\...\vlc.h ....\..\......\Makefile ....\..\......\src ....\..\......\...\annexb.c ....\..\......\...\biaridecod.c ....\..\......\...\block.c ....\..\......\...\cabac.c ....\..\......\...\context_ini.c ....\..\......\...\erc_api.c ....\..\......\...\erc_do_i.c ....\..\......\...\erc_do_p.c ....\..\......\...\errorconcealment.c ....\..\......\...\filehandle.c ....\..\......\...\fmo.c ....\..\......\...\header.c ....\..\......\...\image.c ....\..\......\...\ldecod.c ....\..\......\...\leaky_bucket.c ....\..\......\...\loopFilter.c ....\..\......\...\macroblock.c ....\..\......\...\mbuffer.c ....\..\......\...\mb_access.c ....\..\......\...\memalloc.c ....\..\......\...\nal.c ....\..\......\...\nalu.c ....\..\......\...\nalucommon.c ....\..\......\...\nal_part.c ....\..\......\...\output.c ....\..\......\...\parset.c ....\..\......\...\parsetcommon.c ....\..\......\...\rtp.c ....\..\......\...\sei.c ....\..\......\...\vlc.c ....\..\ldecod.dsp ....\..\ldecod.dsw ... ...

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值