EasyRTMP视频直播推送H264 sps解析错误导致播放画面拉伸问题解决
来源:互联网 发布:python 逆矩阵 编辑:程序博客网 时间:2024/06/05 20:15
EasyRTMP是将H264流以及AAC流以RTMP协议推送到RTMP服务器上进行直播。EasyRTMP推送库中会从H264流中提取中SPS、PPS进行解析,开发的时候遇到过有些SPS解析有误,获取到的宽高不正确,导致播放的时候画面被拉长的问题。下面给出一份比较完善的SPS解析
SPS解析
定义sps结构
typedef struct{ int i_id; int i_profile_idc; int i_level_idc; int b_constraint_set0; int b_constraint_set1; int b_constraint_set2; int i_chroma_format_idc; int i_log2_max_frame_num; int i_poc_type; /* poc 0 */ int i_log2_max_poc_lsb; /* poc 1 */ int b_delta_pic_order_always_zero; int i_offset_for_non_ref_pic; int i_offset_for_top_to_bottom_field; int i_num_ref_frames_in_poc_cycle; int i_offset_for_ref_frame[256]; int i_num_ref_frames; int b_gaps_in_frame_num_value_allowed; int i_mb_width; int i_mb_height; int b_frame_mbs_only; int b_mb_adaptive_frame_field; int b_direct8x8_inference; int b_crop; struct { int i_left; int i_right; int i_top; int i_bottom; } crop; int b_vui; struct { int b_aspect_ratio_info_present; int i_sar_width; int i_sar_height; int b_overscan_info_present; int b_overscan_info; int b_signal_type_present; int i_vidformat; int b_fullrange; int b_color_description_present; int i_colorprim; int i_transfer; int i_colmatrix; int b_chroma_loc_info_present; int i_chroma_loc_top; int i_chroma_loc_bottom; int b_timing_info_present; int i_num_units_in_tick; int i_time_scale; int b_fixed_frame_rate; int nal_hrd_parameters_present_flag; int vcl_hrd_parameters_present_flag; int pic_struct_present_flag; int b_bitstream_restriction; int b_motion_vectors_over_pic_boundaries; int i_max_bytes_per_pic_denom; int i_max_bits_per_mb_denom; int i_log2_max_mv_length_horizontal; int i_log2_max_mv_length_vertical; int i_num_reorder_frames; int i_max_dec_frame_buffering; /* FIXME to complete */ } vui; int b_qpprime_y_zero_transform_bypass; int scaling_matrix_present; uint8_t scaling_matrix4[6][16]; uint8_t scaling_matrix8[6][64];} h264_sps_t;
解析SPS数据,得到h264_sps_t结构的数据
/* return -1 if invalid, else the id */int h264_sps_read( unsigned char *nal, int nal_len, h264_sps_t *sps){ int i_profile_idc; int i_level_idc; int b_constraint_set0; int b_constraint_set1; int b_constraint_set2; int id; bs_t bs; bs_t *s = &bs; sps->scaling_matrix_present = 0; bs_init( &bs, nal+1, nal_len-1 ); //P264_TRACE_ADDRESS(); i_profile_idc = bs_read( s, 8 ); //_TRACE2("SPS: profile_idc = %d\n", i_profile_idc); b_constraint_set0 = bs_read( s, 1 ); b_constraint_set1 = bs_read( s, 1 ); b_constraint_set2 = bs_read( s, 1 ); bs_skip( s, 5 ); /* reserved */ //P264_TRACE_ADDRESS(); i_level_idc = bs_read( s, 8 ); //_TRACE2("SPS: level_idc = %d\n", i_level_idc); id = bs_read_ue( s ); if( bs_eof( s ) || id >= 32 ) { /* the sps is invalid, no need to corrupt sps_array[0] */ return -1; } sps->i_id = id; /* put pack parsed value */ sps->i_profile_idc = i_profile_idc; sps->i_level_idc = i_level_idc; sps->b_constraint_set0 = b_constraint_set0; sps->b_constraint_set1 = b_constraint_set1; sps->b_constraint_set2 = b_constraint_set2; if(sps->i_profile_idc >= 100){ //high profile sps->i_chroma_format_idc= bs_read_ue( s ); if(sps->i_chroma_format_idc >= 32 ) return -1; if(sps->i_chroma_format_idc == 3) bs_read( s, 1 );//residual_color_transform_flag //sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; //sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; //sps->transform_bypass = get_bits1(&s->gb); /* bit_depth_luma_minus8 */ bs_read_ue( s ); /* bit_depth_chroma_minus8 */ bs_read_ue( s ); /* qpprime_y_zero_transform_bypass_flag */ bs_skip( s, 1 ); /* seq_scaling_matrix_present_flag */ int seq_scaling_matrix_present_flag = bs_read( s, 1 ); //decode_scaling_matrices(s, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); if (seq_scaling_matrix_present_flag) { for( int i = 0; i < ((3 != sps->i_chroma_format_idc) ? 8 : 12); i++ ) { /* seq_scaling_list_present_flag[i] */ seq_scaling_matrix_present_flag = bs_read( s, 1 ); if( !seq_scaling_matrix_present_flag ) continue; const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64; /* scaling_list (...) */ int i_lastscale = 8; int i_nextscale = 8; for( int j = 0; j < i_size_of_scaling_list; j++ ) { if( i_nextscale != 0 ) { /* delta_scale */ seq_scaling_matrix_present_flag = bs_read_se( s ); i_nextscale = ( i_lastscale + seq_scaling_matrix_present_flag + 256 ) % 256; /* useDefaultScalingMatrixFlag = ... */ } /* scalinglist[j] */ i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale; } } } } //sps->i_log2_max_frame_num = bs_read_ue( s ) + 4; //sps->i_log2_max_frame_num = 2^(bs_read_ue( s ) + 4); sps->i_log2_max_frame_num = bs_read_ue( s ); sps->i_poc_type = bs_read_ue( s ); if( sps->i_poc_type == 0 ) { sps->i_log2_max_poc_lsb = bs_read_ue( s ) + 4; } else if( sps->i_poc_type == 1 ) { int i; sps->b_delta_pic_order_always_zero = bs_read( s, 1 ); sps->i_offset_for_non_ref_pic = bs_read_se( s ); sps->i_offset_for_top_to_bottom_field = bs_read_se( s ); sps->i_num_ref_frames_in_poc_cycle = bs_read_ue( s ); if( sps->i_num_ref_frames_in_poc_cycle > 256 ) { /* FIXME what to do */ sps->i_num_ref_frames_in_poc_cycle = 256; } for( i = 0; i < sps->i_num_ref_frames_in_poc_cycle; i++ ) { sps->i_offset_for_ref_frame[i] = bs_read_se( s ); } } else if( sps->i_poc_type > 2 ) { goto error; } sps->i_num_ref_frames = bs_read_ue( s ); //_TRACE2("SPS: num_ref_frames = %d\n", sps->i_num_ref_frames); sps->b_gaps_in_frame_num_value_allowed = bs_read( s, 1 ); sps->i_mb_width = bs_read_ue( s ) + 1; //_TRACE2("SPS: mb_width = %d\n", sps->i_mb_width); sps->i_mb_height= bs_read_ue( s ) + 1; //_TRACE2("SPS: mb_height = %d\n", sps->i_mb_height); sps->b_frame_mbs_only = bs_read( s, 1 ); if( !sps->b_frame_mbs_only ) { sps->b_mb_adaptive_frame_field = bs_read( s, 1 ); } else { sps->b_mb_adaptive_frame_field = 0; } sps->b_direct8x8_inference = bs_read( s, 1 ); sps->b_crop = bs_read( s, 1 ); if( sps->b_crop ) { sps->crop.i_left = bs_read_ue( s ); sps->crop.i_right = bs_read_ue( s ); sps->crop.i_top = bs_read_ue( s ); sps->crop.i_bottom= bs_read_ue( s ); } else { sps->crop.i_left = 0; sps->crop.i_right = 0; sps->crop.i_top = 0; sps->crop.i_bottom= 0; } sps->b_vui = bs_read( s, 1 ); if( sps->b_vui ) { /* FIXME */ //_TRACE2( "decode vui %d\n", bs_pos(s) ); decode_vui_parameters(s, sps); } if( bs_eof( s ) ) { /* no rbsp trailing */ //_TRACE2( "incomplete SPS\n" ); sps->i_id = -1; return -1000; } return id;error: /* invalidate this sps */ sps->i_id = -1; return -1;}
获取更多信息
邮件:support@easydarwin.org
WEB:www.EasyDarwin.org
Copyright © EasyDarwin.org 2012-2016
0 0
- EasyRTMP视频直播推送H264 sps解析错误导致播放画面拉伸问题解决
- EasyRTMP之H264 SPS解析宽高不正确导致播放时画面拉伸的问题修复(五)
- EasyPusher EasyRTMP视频直播推送中对H264帧类型判断
- EasyRTMP推送RTSP视频源进行RTMP直播
- EasyRTMP手机直播推送rtmp流flash无法正常播放问题
- [转载]使用EasyRTMP推送RTMP流flash播放器无法正常播放的问题解决
- [转载]使用EasyRTSPClient与EasyRTMP推送RTSP视频源进行RTMP直播
- H264 sps pps 解析
- EasyRTMP之RTMP直播高效推送缓冲区
- H264视频的sps和pps解析和哥伦布编码
- EasyRTMP实现Demux解析MP4文件进行rtmp推送实现RTMP直播功能
- H264 SPS 序列解析整理
- ijkplayer的使用解析-视频播放,直播
- EasyRTMP实现RTMP异步直播推送之环形缓冲区设计
- 关于h264视频的sps和pps解析和哥伦布编码
- RTMP推送直播H264/AAC编码的音视频采集数据
- H264视频通过RTMP直播
- H264视频通过RTMP直播 .
- 跨域请求之jQuery的ajax jsonp的使用
- 【大风】水仙花数最简短,运行速度最快的代码
- 2010南海初中竞赛 蜡烛
- Dom4j方法写入XML文件
- web
- EasyRTMP视频直播推送H264 sps解析错误导致播放画面拉伸问题解决
- 如何识别牛逼的前端工程师
- Linux下用文件IO的方式操作GPIO
- Android 与 H5 数据的传递
- Caffe-faster-rcnn demo测试
- python decorator实例
- xss攻击进阶篇---如何利用抓包工具Fiddler进行xss攻击
- C语言二维数组作为函数的参数
- HDU 1175 连连看【回溯】