转自:http://www.cnblogs.com/likwo/p/3531241.html

在使用ffmpeg解码播放TS流的时候(例如之前写过的UDP组播流),在连接时往往需要耗费大量时间。经过debug发现是av_find_stream_info(已抛弃,现在使用的是avformat_find_stream_info)这个方法十分耗时,而且是阻塞的。av_find_stream_info方法主要是获得相应的流信息,其中对我的应用最有用的就是视频的分辨率。在av_find_stream_info中是要不断的读取数据包,解码获得相应的信息,而其中除了分辨率信息以外的东西对我的应用中是无用的。所以,考虑自己手动从H.264码流中解析出视频的分辨率信息。

以下内容主要参考了这篇文章:http://www.myexception.cn/internet/586390.html

H.264码流的流信息都存储在了特殊的结构中,叫做SPS(Sequence Parameter Set)。要解析SPS就需要知道一些H.264码流的格式信息。

在H.264码流中,都是以0x00 0x00 0x01 或者 0x00 0x00 0x00 0x01为开始码的(在我的应用中为后者),之后通过检测开始码后第一个字节的后五位是否为7(00111)来判断其是否为SPS。得到SPS之后,就可以解析出视频的分辨率。SPS中有两个成员,pic_width_in_mbs_minus1和pic_height_in_map_units_minus_1,分别表示图像的宽和高,但是要注意的是它们都是以16为单位(在面积上就是以16*16的块为单位)再减1,所以实际的宽是(pic_width_in_mbs_minus1 + 1)*16,高为(pic_height_in_map_units_minus_1+1)*16。

欢迎转载,转载请注明出处:http://guoyb.com/Tech/34.html

以下是解析宽高的代码:

转载http://guoyb.com/Tech/34.html

以下部分 转自 http://blog.csdn.net/pkueecser/article/details/7367641

使用RTP传输H264的时候,需要用到sdp协议描述,其中有两项:Sequence Parameter Sets (SPS) 和Picture Parameter Set (PPS)需要用到,那么这两项从哪里获取呢?答案是从H264码流中获取.在H264码流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"为开始码的,找到开始码之后,使用开始码之后的第一个字节的低5位判断是否为7(sps)或者8(pps), 及data[4] & 0x1f == 7 || data[4] & 0x1f == 8.然后对获取的nal去掉开始码之后进行base64编码,得到的信息就可以用于sdp.sps和pps需要用逗号分隔开来.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

如何解析SDP中包含的H.264的SPS和PPS串

http://www.pernet.tv.sixxs.org/thread-109-1-1.html

SDP中的H.264的SPS和PPS串,包含了初始化H.264解码器所需要的信息参数,包括编码所用的profile,level,图像的宽和高,deblock滤波器等。
由于SDP中的SPS和PPS都是BASE64编码形式的,不容易理解,附件有一个工具软件可以对SDP中的SPS和PPS进行解析。
用法是在命令行中输入:
spsparser sps.txt pps.txt output.txt

例如sps.txt中的内容为:
Z0LgFNoFglE=
pps.txt中的内容为:
aM4wpIA=

最终解析的到的结果为:

Start dumping SPS:
  profile_idc = 66
  constrained_set0_flag = 1
  constrained_set1_flag = 1
  constrained_set2_flag = 1
  constrained_set3_flag = 0
  level_idc = 20
  seq_parameter_set_id = 0
  chroma_format_idc = 1
  bit_depth_luma_minus8 = 0
  bit_depth_chroma_minus8 = 0
  seq_scaling_matrix_present_flag = 0
  log2_max_frame_num_minus4 = 0
  pic_order_cnt_type = 2
  log2_max_pic_order_cnt_lsb_minus4 = 0
  delta_pic_order_always_zero_flag = 0
  offset_for_non_ref_pic = 0
  offset_for_top_to_bottom_field = 0
  num_ref_frames_in_pic_order_cnt_cycle = 0
  num_ref_frames = 1
  gaps_in_frame_num_value_allowed_flag = 0
  pic_width_in_mbs_minus1 = 21
  pic_height_in_mbs_minus1 = 17
  frame_mbs_only_flag = 1
  mb_adaptive_frame_field_flag = 0
  direct_8x8_interence_flag = 0
  frame_cropping_flag = 0
  frame_cropping_rect_left_offset = 0
  frame_cropping_rect_right_offset = 0
  frame_cropping_rect_top_offset = 0
  frame_cropping_rect_bottom_offset = 0
  vui_parameters_present_flag = 0

Start dumping PPS:
  pic_parameter_set_id = 0
  seq_parameter_set_id = 0
  entropy_coding_mode_flag = 0
  pic_order_present_flag = 0
  num_slice_groups_minus1 = 0
  slice_group_map_type = 0
  num_ref_idx_l0_active_minus1 = 0
  num_ref_idx_l1_active_minus1 = 0
  weighted_pref_flag = 0
  weighted_bipred_idc = 0
  pic_init_qp_minus26 = 0
  pic_init_qs_minus26 = 0
  chroma_qp_index_offset = 10
  deblocking_filter_control_present_flag = 1
  constrained_intra_pred_flag = 0
  redundant_pic_cnt_present_flag = 0
  transform_8x8_mode_flag = 0
  pic_scaling_matrix_present_flag = 0
  second_chroma_qp_index_offset = 10

/////////////////////////////////////////////////////////////////////////////////////////////////
这里需要特别提一下这两个参数
pic_width_in_mbs_minus1 = 21
  pic_height_in_mbs_minus1 = 17
分别表示图像的宽和高,以宏块(16x16)为单位的值减1
因此,实际的宽为 (21+1)*16 = 352
 spsparser.rar

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

http://krdai.info.sixxs.org/blog/mp4-sps-pps-data.html

最近在做跟 h264 encode/decode 相關的研究,目標是希望可以從 Android 的 MediaRecorder 當中取出 h264 的資訊。目前問題是在於 SPS 以及 PPS 到底要怎樣得到。由於 MediaRecorder 是寫入 mp4 檔案中,所以不得已只好來去分析一下 mp4 的檔案格式,發現沒有想像中的困難. 主要是參照 ISO/IEC 14496-15 這部份. 在 mp4 的檔案之中, 找到 avcC 這個字串, 之後就是接上 AVCDecoderConfigurationRecord. AVCDecoderConfigurationRecord 的 format 如下:

  1. aligned(8) class AVCDecoderConfigurationRecord {
  2. unsigned int(8) configurationVersion = 1;
  3. unsigned int(8) AVCProfileIndication;
  4. unsigned int(8) profile_compatibility;
  5. unsigned int(8) AVCLevelIndication;
  6. bit(6) reserved = '111111'b;
  7. unsigned int(2) lengthSizeMinusOne;
  8. bit(3) reserved = '111'b;
  9. unsigned int(5) numOfSequenceParameterSets;
  10. for (i=0; i< numOfSequenceParameterSets; i++) {
  11. unsigned int(16) sequenceParameterSetLength ;
  12. bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;
  13. }
  14. unsigned int(8) numOfPictureParameterSets;
  15. for (i=0; i< numOfPictureParameterSets; i++) {
  16. unsigned int(16) pictureParameterSetLength;
  17. bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;
  18. }
  19. }

對照一下這樣就可以找到 SPS 和 PPS

+++++++++++++++++++++++++++++++++++++++++++++
 
vlc没有收到pps和sps
2010-10-08 16:16
问题 packetizer_h264 packetizer warning: waiting for SPS/PPS

是因为解码器只是在第一次执行编码的时候,才编码出 SPS、PPS、和I_Frame;

h264 packetizer has set so, that it sends sps/pps only first keyframe,
 I'm trying to figure what breaks if that is changed so sps/pps is written in every keyframe.
[出自| http://trac.videolan.org/vlc/ticket/1384]

解决办法:

1、编码器编码出每个关键帧都加上SPS、PPS ,据说通常情况编码器编出的 SPS、PPS是一样的,所以这种方法耗费资源。

2、在服务器接收到客户端请求时,发送第一个package 加上 SPS、PPS。

具体如下:

  • 1、在 VideoOpenFileSource 添加一个变量 isFirstFrame;

  • 2、构造时初始化 isFirstFrame = true;
  • 3、在int VideoOpenFileSource::readFromBufferChain() 修改如下:

  •    1         if(isFirstFrame == true)
    2 {
    3 memcpy(fTo, h264_header, sizeof(h264_header)); /* h264_header = pps +sps*/
    4 offset = sizeof(h264_header);
    5 framesize = BufferChain_get(fInput.video_bufs, fTo + offset);
    6 offset += framesize;
    7 isFirstFrame = false;
    8 printf("this is the first fime\n");
    9 sleep(1);
    10 }
    11 else
    12 {
    13 framesize = BufferChain_get(fInput.video_bufs, fTo + offset);
    14 offset += framesize;
    15 }
    1
[http://topic.csdn.net/u/20100801/17/ef35e664-92ff-4144-a35f-3984dcf11da3.html| 参考] 

========================================================================
sdp 关于pps和sps的疑问:
packetization-mode 主要是定义包的模式,单一 NALU单元模式(0);非交错(non-interleaved)封包模式(1);交错(interleaved)封包模式(2)
sprop-parameter-sets 等于H.264 的序列参数集和图像参数 NAL单元,base64转换;(即= sps+pps)
profile-level-id 这个参数用于指示 H.264 流的 profile 类型和级别。这知道这个是啥东东 参考 黑暗长老 www.cppblog.com/czanyou/
ffmpeg decode 关于pps sps问题:
stackoverflow.com/questions/3493742/problem-to-decode-h264-video-over-rtp-with-ffmpeg-libavcodec/3500432#3500432

如何用C语言取出H.264ES文件里的nal(sps,pps)信息。比如width, height, profile等等

请高手指点指点。。。 http://www.oschina.net/question/225813_35707

解析sps,pps的代码在ffmpeg里面就有, 抄出来就行了, 我以前也自己写过...
ffmpeg的libavcodec/h264_parser.c,
h264_ps.c
函数
ff_h264_decode_seq_parameter_set
ff_h264_decode_picture_parameter_set
自己可以看代码.

H264参数语法文档: SPS、PPS、IDR http://blog.csdn.net/heanyu/article/details/6205390

H.264码流第一个 NALU 是 SPS(序列参数集Sequence Parameter Set)
对应H264标准文档 7.3.2.1 序列参数集的语法进行解析

获得H.264视频分辨率的方法的更多相关文章

  1. H.264视频在android手机端的解码与播放(转)

    随着无线网络和智能手机的发展,智能手机与人们日常生活联系越来越紧密,娱乐.商务应用.金融应用.交通出行各种功能的软件大批涌现,使得人们的生活丰富多彩.快捷便利,也让它成为人们生活中不可取代的一部分.其 ...

  2. 视音频数据处理入门:H.264视频码流解析

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  3. H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式(包含AAC部分解析)

    H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +------------ ...

  4. 【转】实现RTP协议的H.264视频传输系统

    1.  引言       随着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性.但人们又面临着另外一种不可避免的尴尬,就是在网络上看到生动 ...

  5. H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式

    H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +------------ ...

  6. H.264视频的RTP荷载格式

    Status of This Memo This document specifies an Internet standards track protocol for the   Internet ...

  7. 对H.264帧类型判断方法

    背景描述 我们经常在网络直播推流或者客户端拉流的时候,需要对获取到的H.264视频帧进行判断后处理,我们经常获取到各种不同的视频数据0x67 0x68 0x65 0x61,0x27 0x28 0x25 ...

  8. 屏幕录制H.264视频,AAC音频,MP4复,LibRTMP现场活动

    上周完成了一个屏幕录制节目,实时屏幕捕获.记录,视频H.264压缩,音频应用AAC压缩,复用MP4格公式,这使得计算机和ios设备上直接播放.支持HTML5的播放器都能够放,这是标准格式的优点.抓屏也 ...

  9. 【图像处理】DVR H.264视频编码基本知识

    视频编码技术基本是由ISO/IEC制定的MPEG-x和ITU-T制定的H.26x两大系列视频编码国际标准的推出.从H.261视频编码建议,到 H.262/3.MPEG-1/2/4等都有一个共同的不断追 ...

随机推荐

  1. keepalived和heartbeat区别

    <1>Keepalived使用的vrrp协议方式,虚拟路由冗余协议 (Virtual Router Redundancy Protocol,简称VRRP):Heartbeat是基于主机或网 ...

  2. 使用 MongoDB 的_id 查询

    MongoDB 默认在插入数据时,生成一个主键_id,那么怎么使用_id来查询数据? 查询全部 > db.foo.find(){ "_id" : ObjectId(" ...

  3. 在win7-64bit环境下,boa-constructor 0.6.1 的palette面板中没有控件图标的解决方法

    在win7-64bit环境下,boa-constructor 0.6.1 的palette面板中没有控件图标,空白一片.将面板窗口拉大,发现那些图标在很下面的位置,X轴的排列与正常状态一致. 软件环境 ...

  4. http get vs post

    http get vs post GET与POST方法有以下区别:(1) 在客户端,Get方式在通过URL提交数据,数据在URL中可以看到:POST方式,数据放置在HTML HEADER内提交.(2) ...

  5. mysql日常语句总结

    #删除mysql的二进制日志文件 #将删除mysql-bin.*****1之前的日志文件 purge binary logs to 'mysql-bin.*****1'; #重新生成一个二进制日志文件 ...

  6. 数组里的数据绑定到dataset中

    string [] an = {"a","b","c"};DataTable dt = new DataTable(); dt.Column ...

  7. Effective C++ -----条款33:避免遮掩继承而来的名称

    derived classes内的名称会遮掩base classes内的名称.在public继承下从来没有人希望如此. 为了让被遮掩的名称再见天日,可使用using声明式或转交函数(forwardin ...

  8. 【linux】vim的一些快捷键

    ctrl+y  :重复上一行内容 v+移动光标  :选择内容 y  :复制选中的内容 p  :在光标处粘贴复制的内容 ctrl+v :进入列模式,可以选择多列数据 dd :剪切一行,也可做删除一行使用

  9. LightOJ 1236 - Pairs Forming LCM(素因子分解)

    B - Pairs Forming LCM Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  10. Maven Java EE Configuration Problem 的完美解决办法

    背景: 最近在修改项目的时候,发现修改了项目依赖以后会出现如下图:Maven Java EE Configuration Problem 的问题,对于有强迫症的我来说,看到项目上面有个很小的红色小叉号 ...