关于h264bitstream的bug修正及完善

来源:互联网 发布:淘宝消费积分 编辑:程序博客网 时间:2024/05/22 12:28

最近学习HEVC,参考h264bitstream开源库重新写代码解析码流。在观察H264码流的分析结果时,发现该库分析的结果与商业工具有些不同。以前也遇到过,还写了篇文章《解决h264bitstream的一个bug》,经调试发现h264bitstream库实现上有些小问题,于是就修改修改,形成此文。

一、头文件

1、改名及新加

将sps_t结构体的residual_colour_transform_flag改名为separate_colour_plane_flag。根据最新文档,sps_t结构体新加ChromaArrayType。slice_header_t结构体添加colour_plane_id成员。

2、新加vector

去掉extern "C"的限制,添加std的vector。

#include <vector>
using std::vector;

3、分离部分结构体

将slice_header_t结构体的pwt、rplr和drpm独立出来。因为这些字段的数量不固定,使用了vector存储,代码如下:

// predictive weight tabletypedef struct{    int luma_log2_weight_denom;    int chroma_log2_weight_denom;    int luma_weight_l0_flag[64];    int luma_weight_l0[64];    int luma_offset_l0[64];    int chroma_weight_l0_flag[64];    int chroma_weight_l0[64][2];    int chroma_offset_l0[64][2];    int luma_weight_l1_flag[64];    int luma_weight_l1[64];    int luma_offset_l1[64];    int chroma_weight_l1_flag[64];    int chroma_weight_l1[64][2];    int chroma_offset_l1[64][2];} pwt_t;// ref pic list modificationtypedef struct{    int modification_of_pic_nums_idc;    int abs_diff_pic_num_minus1;    int long_term_pic_num;} rplm_tt;typedef struct{    int ref_pic_list_modification_flag_l0;    int ref_pic_list_modification_flag_l1;    vector<rplm_tt> rplm;} rplm_t;// decoded ref pic markingtypedef struct{    int memory_management_control_operation;    int difference_of_pic_nums_minus1;    int long_term_pic_num;    int long_term_frame_idx;    int max_long_term_frame_idx_plus1;} drpm_tt;typedef struct{    int no_output_of_prior_pics_flag;    int long_term_reference_flag;    int adaptive_ref_pic_marking_mode_flag;    vector<drpm_tt> drpm;} drpm_t;


slice_header_t对应的变更如下:

pwt_t pwt;rplm_t rplm;drpm_t drpm;


二、实现文件

1、将read_ref_pic_list_reordering函数改名为read_ref_pic_list_modification。根据不同的数值添加到vector中。实现变更如下:

//7.3.3.1 Reference picture list modification syntaxvoid read_ref_pic_list_modification(h264_stream_t* h, bs_t* b){    slice_header_t* sh = h->sh;    rplm_tt rplmtt;    if( ! is_slice_type( sh->slice_type, SH_SLICE_TYPE_I ) && ! is_slice_type( sh->slice_type, SH_SLICE_TYPE_SI ) )    {        sh->rplm.ref_pic_list_modification_flag_l0 = bs_read_u1(b);        if( sh->rplm.ref_pic_list_modification_flag_l0 )        {            do            {                rplmtt.modification_of_pic_nums_idc = bs_read_ue(b);                if( rplmtt.modification_of_pic_nums_idc == 0 ||                    rplmtt.modification_of_pic_nums_idc == 1 )                {                    rplmtt.abs_diff_pic_num_minus1 = bs_read_ue(b);                }                else if( rplmtt.modification_of_pic_nums_idc == 2 )                {                    rplmtt.long_term_pic_num = bs_read_ue(b);                }                sh->rplm.rplm.push_back(rplmtt);            } while( rplmtt.modification_of_pic_nums_idc != 3 && ! bs_eof(b) );        }    }    if( is_slice_type( sh->slice_type, SH_SLICE_TYPE_B ) )    {        sh->rplm.ref_pic_list_modification_flag_l1 = bs_read_u1(b);        if( sh->rplm.ref_pic_list_modification_flag_l1 )        {            do            {                rplmtt.modification_of_pic_nums_idc = bs_read_ue(b);                if( rplmtt.modification_of_pic_nums_idc == 0 ||                    rplmtt.modification_of_pic_nums_idc == 1 )                {                    rplmtt.abs_diff_pic_num_minus1 = bs_read_ue(b);                }                else if( rplmtt.modification_of_pic_nums_idc == 2 )                {                    rplmtt.long_term_pic_num = bs_read_ue(b);                }                sh->rplm.rplm.push_back(rplmtt);            } while( rplmtt.modification_of_pic_nums_idc != 3 && ! bs_eof(b) );        }    }}

2、与上类似,read_dec_ref_pic_marking函数变更如下:

//7.3.3.3 Decoded reference picture marking syntaxvoid read_dec_ref_pic_marking(h264_stream_t* h, bs_t* b){    slice_header_t* sh = h->sh;    drpm_tt drpmtt;    if( h->nal->nal_unit_type == 5 )    {        sh->drpm.no_output_of_prior_pics_flag = bs_read_u1(b);        sh->drpm.long_term_reference_flag = bs_read_u1(b);    }    else    {        sh->drpm.adaptive_ref_pic_marking_mode_flag = bs_read_u1(b);        if( sh->drpm.adaptive_ref_pic_marking_mode_flag )        {            do            {                drpmtt.memory_management_control_operation = bs_read_ue(b);                if( drpmtt.memory_management_control_operation == 1 ||                    drpmtt.memory_management_control_operation == 3 )                {                    drpmtt.difference_of_pic_nums_minus1 = bs_read_ue(b);                }                if(drpmtt.memory_management_control_operation == 2 )                {                    drpmtt.long_term_pic_num = bs_read_ue(b);                }                if( drpmtt.memory_management_control_operation == 3 ||                    drpmtt.memory_management_control_operation == 6 )                {                    drpmtt.long_term_frame_idx = bs_read_ue(b);                }                if( drpmtt.memory_management_control_operation == 4 )                {                    drpmtt.max_long_term_frame_idx_plus1 = bs_read_ue(b);                }                sh->drpm.drpm.push_back(drpmtt);            } while( drpmtt.memory_management_control_operation != 0 && ! bs_eof(b) );        }    }}


3、read_pred_weight_table函数中使用的num_ref_idx_l0_active_minus1为pps_t结构体的,这是错误的。正确的是使用slice_header_t结构体的num_ref_idx_l0_active_minus1。

for( i = 0; i <= pps->num_ref_idx_l0_active_minus1; i++ )

要更改为

for( i = 0; i <= sh->num_ref_idx_l0_active_minus1; i++ )


其它一些细小的修改不在此文列出。源代码见github仓库:https://github.com/latelee/H264BSAnalyzer的Branch_dev分支。具体如下:
https://github.com/latelee/H264BSAnalyzer/blob/Branch_dev/H264BSAnalyzer/h264_stream.h

https://github.com/latelee/H264BSAnalyzer/blob/Branch_dev/H264BSAnalyzer/h264_stream.cpp


李迟 2015.9.28 晚

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机滑不动怎么办 升级失败白苹果怎么办 6s屏幕不准怎么办 苹果4s充不进电怎么办 苹果4sbi锁怎么办 乐视pro3充电慢怎么办 手机屏幕触碰不灵敏怎么办 手机换屏幕失灵怎么办 手机图标有重影怎么办 苹果屏幕太灵敏怎么办 5s触摸不灵敏怎么办 导航触屏失灵怎么办 汽车导航触摸屏失灵怎么办 爱丽舍导航仪触屏失灵怎么办 手机要开机很久怎么办 小米手机屏失灵怎么办 5s手机屏幕松动怎么办 手机按钮不灵了怎么办 手机触摸屏不灵了怎么办 mac触摸板失灵怎么办 苹果屏幕触摸失灵怎么办 三星手机屏幕没反应怎么办 手机开机定屏怎么办 手机触摸局部失灵怎么办 苹果手机屏幕按键失灵怎么办 5s锁屏键坏了怎么办 平板版本太低怎么办 手机屏局部失灵怎么办 iphone8触屏不灵敏怎么办 苹果机8屏幕失灵怎么办 车钥匙丢车上怎么办 指纹锁华盖坏了怎么办 非法入了户口怎么办 司考成绩单丢了怎么办 小饭桌转让手续怎么办 两个领导不和你怎么办 两个领导意见不一致怎么办 两个领导对立我怎么办 投诉申通没用怎么办 领导作风有问题怎么办 做完火疗受风了难受怎么办