当前位置: 首页 > news >正文

家居网站建设咨询网站建设方案设计是什么意思

家居网站建设咨询,网站建设方案设计是什么意思,ps如何做网站专题,谷歌海外推广怎么做一直想写一个HEVC的码流解析工具#xff0c;看了雷神264码流解析工具#xff0c;本来想尝试模仿写一个相似的265码流分析工具#xff0c;但是发现265的解码过程和结构体和264的不太一样#xff0c;很多结构体并没有完全暴露出来#xff0c;没有想到很好的方法获得量化参数…一直想写一个HEVC的码流解析工具看了雷神264码流解析工具本来想尝试模仿写一个相似的265码流分析工具但是发现265的解码过程和结构体和264的不太一样很多结构体并没有完全暴露出来没有想到很好的方法获得量化参数运动向量等这些信息。想着从头学习一下ffmpeg中的265解码函数再来获取解码后的量化参数运动向量等一系列信息再做码流分析。 这里主要学习HEVC的解析函数代码 众所周知解码器是标准的因此只要按照官方给定的解码流程对码流进行解码就能正常解码。以前不知道下图这种语法元素描述的作用最近才知道解码器的代码完全和描述对的上就是伪代码形式难怪雷神说parse vpsspspps的代码没什么技术含量 ffmpeg为了封装成多种编解码器是提供了包装函数这些函数根据提供编解码标准来选择解码器。我主要看的是HEVC解码不过其他的解码器也相似。 参考我前面的博客经过一堆初始化函数后首先进行的是av_parser_parse2()函数对码流进行解析。主要是VPSSPSPPS进行解码。 av_parser_parse2( ) //此代码位于libavcodec\parser.c中 int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx,uint8_t **poutbuf, int *poutbuf_size,const uint8_t *buf, int buf_size,int64_t pts, int64_t dts, int64_t pos) {int index, i;uint8_t dummy_buf[AV_INPUT_BUFFER_PADDING_SIZE];av_assert1(avctx-codec_id ! AV_CODEC_ID_NONE);/* Parsers only work for the specified codec ids. */av_assert1(avctx-codec_id s-parser-codec_ids[0] ||avctx-codec_id s-parser-codec_ids[1] ||avctx-codec_id s-parser-codec_ids[2] ||avctx-codec_id s-parser-codec_ids[3] ||avctx-codec_id s-parser-codec_ids[4] ||avctx-codec_id s-parser-codec_ids[5] ||avctx-codec_id s-parser-codec_ids[6]);if (!(s-flags PARSER_FLAG_FETCHED_OFFSET)) {s-next_frame_offset s-cur_offset pos;s-flags | PARSER_FLAG_FETCHED_OFFSET;}if (buf_size 0) {/* padding is always necessary even if EOF, so we add it here */memset(dummy_buf, 0, sizeof(dummy_buf));buf dummy_buf;} else if (s-cur_offset buf_size ! s-cur_frame_end[s-cur_frame_start_index]) { /* skip remainder packets *//* add a new packet descriptor */i (s-cur_frame_start_index 1) (AV_PARSER_PTS_NB - 1);s-cur_frame_start_index i;s-cur_frame_offset[i] s-cur_offset;s-cur_frame_end[i] s-cur_offset buf_size;s-cur_frame_pts[i] pts;s-cur_frame_dts[i] dts;s-cur_frame_pos[i] pos;}if (s-fetch_timestamp) {s-fetch_timestamp 0;s-last_pts s-pts;s-last_dts s-dts;s-last_pos s-pos;ff_fetch_timestamp(s, 0, 0, 0);}/* WARNING: the returned index can be negative */// 从这里进入码流解析parser_parse是一个函数指针在hevc的解码过程中会指向hevc_parse()函数,// 此代码位于libavcodec\hevc_parser.c中后续其他的解析函数也均在此文件内。// s-parser在av_parser_init()函数中被赋值。// 通过av_parser_iterate()遍历来寻找对应的解析结构体这个函数的定义位于libavcodec\parser.c中这个文件里面的parser_list通过#include libavcodec/parser_list.c导入// 但是没有找到原始文件里面有这个文件后面发现这个文件是在configure后生成的类似的生成文件还包括codec_list.cindex s-parser-parser_parse(s, avctx, (const uint8_t **) poutbuf,poutbuf_size, buf, buf_size);// 这个函数里面会调用对应编码标准的解析函数这里会调用hevc_parse()函数。av_assert0(index -0x20000000); // The API does not allow returning AVERROR codes #define FILL(name) if(s-name 0 avctx-name 0) avctx-name s-nameif (avctx-codec_type AVMEDIA_TYPE_VIDEO) {FILL(field_order);FILL(coded_width);FILL(coded_height);FILL(width);FILL(height);}/* update the file pointer */if (*poutbuf_size) {/* fill the data for the current frame */s-frame_offset s-next_frame_offset;/* offset of the next frame */s-next_frame_offset s-cur_offset index;s-fetch_timestamp 1;} else {/* Dont return a pointer to dummy_buf. */*poutbuf NULL;}if (index 0)index 0;s-cur_offset index;return index; }hevc_parse( ) hevc_parse()位于libavcodec\hevc_parser.c这个函数主要是解析额外数据获得完整帧数据并进行解析。 static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,const uint8_t **poutbuf, int *poutbuf_size,const uint8_t *buf, int buf_size) {int next;HEVCParserContext *ctx s-priv_data;ParseContext *pc ctx-pc;int is_dummy_buf !buf_size;const uint8_t *dummy_buf buf;// 解析额外的数据主要包含用于存储一些对于编解码过程非必需但又是非常有用的附加信息。这些信息通常是特定于编码的用于初始化编解码器。if (avctx-extradata !ctx-parsed_extradata) {ff_hevc_decode_extradata(avctx-extradata, avctx-extradata_size, ctx-ps, ctx-sei,ctx-is_avc, ctx-nal_length_size, avctx-err_recognition,1, avctx);ctx-parsed_extradata 1;}if (s-flags PARSER_FLAG_COMPLETE_FRAMES) {next buf_size;} else {next hevc_find_frame_end(s, buf, buf_size);//寻找帧的起始标记也即#define START_CODE 0x000001 /// start_code_prefix_one_3bytes可以用UltraEdit查看码流的16进制表示这样更清晰知道解码的完整流程// 这里将传递的码流组成为一个完整帧数据if (ff_combine_frame(pc, next, buf, buf_size) 0) {*poutbuf NULL;*poutbuf_size 0;return buf_size;}}is_dummy_buf (dummy_buf buf);if (!is_dummy_buf)// 这里开始进行解析parse_nal_units(s, buf, buf_size, avctx);*poutbuf buf;*poutbuf_size buf_size;return next; }parse_nal_units() parse_nal_units()函数位于libavcodec\hevc_parser.c里面主要根据nal的类型分别对VPSSPSPPSSEI等信息进行解析 static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,int buf_size, AVCodecContext *avctx) {HEVCParserContext *ctx s-priv_data;HEVCParamSets *ps ctx-ps;HEVCSEI *sei ctx-sei;int ret, i;/* set some sane default values */s-pict_type AV_PICTURE_TYPE_I;s-key_frame 0;s-picture_structure AV_PICTURE_STRUCTURE_UNKNOWN;ff_hevc_reset_sei(sei);ret ff_h2645_packet_split(ctx-pkt, buf, buf_size, avctx, ctx-is_avc,ctx-nal_length_size, AV_CODEC_ID_HEVC, 1, 0);if (ret 0)return ret;for (i 0; i ctx-pkt.nb_nals; i) {H2645NAL *nal ctx-pkt.nals[i];GetBitContext *gb nal-gb;if (nal-nuh_layer_id 0)continue;switch (nal-type) {case HEVC_NAL_VPS:ff_hevc_decode_nal_vps(gb, avctx, ps);break;case HEVC_NAL_SPS:ff_hevc_decode_nal_sps(gb, avctx, ps, 1);break;case HEVC_NAL_PPS:ff_hevc_decode_nal_pps(gb, avctx, ps);break;case HEVC_NAL_SEI_PREFIX:case HEVC_NAL_SEI_SUFFIX:ff_hevc_decode_nal_sei(gb, avctx, sei, ps, nal-type);break;case HEVC_NAL_TRAIL_N:case HEVC_NAL_TRAIL_R:case HEVC_NAL_TSA_N:case HEVC_NAL_TSA_R:case HEVC_NAL_STSA_N:case HEVC_NAL_STSA_R:case HEVC_NAL_BLA_W_LP:case HEVC_NAL_BLA_W_RADL:case HEVC_NAL_BLA_N_LP:case HEVC_NAL_IDR_W_RADL:case HEVC_NAL_IDR_N_LP:case HEVC_NAL_CRA_NUT:case HEVC_NAL_RADL_N:case HEVC_NAL_RADL_R:case HEVC_NAL_RASL_N:case HEVC_NAL_RASL_R:if (ctx-sei.picture_timing.picture_struct HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING) {s-repeat_pict 1;} else if (ctx-sei.picture_timing.picture_struct HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING) {s-repeat_pict 2;}ret hevc_parse_slice_header(s, nal, avctx);if (ret)return ret;break;}}/* didnt find a picture! */av_log(avctx, AV_LOG_ERROR, missing picture in access unit with size %d\n, buf_size);return -1; }这里主要看了VPSSPS和PPS的函数 VPSSPS和PPS的函数功能都相差不大由于代码过长就不贴了这些函数都位于libavcodec\hevc_ps.c中这里以VPS的解析函数ff_hevc_decode_nal_vps()为例。 下图为VPS的语法元素描述《新一代高效视频编码 H.265/HEVC原理、标准与实现》 每一章都有对应的语法描述或者去官方文件里面查看 int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,HEVCParamSets *ps) {int i,j;int vps_id 0;ptrdiff_t nal_size;HEVCVPS *vps ff_refstruct_allocz(sizeof(*vps));if (!vps)return AVERROR(ENOMEM);av_log(avctx, AV_LOG_DEBUG, Decoding VPS\n);nal_size gb-buffer_end - gb-buffer;if (nal_size sizeof(vps-data)) {av_log(avctx, AV_LOG_WARNING, Truncating likely oversized VPS (%PTRDIFF_SPECIFIER %SIZE_SPECIFIER)\n,nal_size, sizeof(vps-data));vps-data_size sizeof(vps-data);} else {vps-data_size nal_size;}memcpy(vps-data, gb-buffer, vps-data_size);vps_id vps-vps_id get_bits(gb, 4);if (get_bits(gb, 2) ! 3) { // vps_reserved_three_2bitsav_log(avctx, AV_LOG_ERROR, vps_reserved_three_2bits is not three\n);goto err;}vps-vps_max_layers get_bits(gb, 6) 1;vps-vps_max_sub_layers get_bits(gb, 3) 1;vps-vps_temporal_id_nesting_flag get_bits1(gb);if (get_bits(gb, 16) ! 0xffff) { // vps_reserved_ffff_16bitsav_log(avctx, AV_LOG_ERROR, vps_reserved_ffff_16bits is not 0xffff\n);goto err;}if (vps-vps_max_sub_layers HEVC_MAX_SUB_LAYERS) {av_log(avctx, AV_LOG_ERROR, vps_max_sub_layers out of range: %d\n,vps-vps_max_sub_layers);goto err;}if (parse_ptl(gb, avctx, vps-ptl, vps-vps_max_sub_layers) 0)goto err;vps-vps_sub_layer_ordering_info_present_flag get_bits1(gb);i vps-vps_sub_layer_ordering_info_present_flag ? 0 : vps-vps_max_sub_layers - 1;for (; i vps-vps_max_sub_layers; i) {vps-vps_max_dec_pic_buffering[i] get_ue_golomb_long(gb) 1;vps-vps_num_reorder_pics[i] get_ue_golomb_long(gb);vps-vps_max_latency_increase[i] get_ue_golomb_long(gb) - 1;if (vps-vps_max_dec_pic_buffering[i] HEVC_MAX_DPB_SIZE || !vps-vps_max_dec_pic_buffering[i]) {av_log(avctx, AV_LOG_ERROR, vps_max_dec_pic_buffering_minus1 out of range: %d\n,vps-vps_max_dec_pic_buffering[i] - 1);goto err;}if (vps-vps_num_reorder_pics[i] vps-vps_max_dec_pic_buffering[i] - 1) {av_log(avctx, AV_LOG_WARNING, vps_max_num_reorder_pics out of range: %d\n,vps-vps_num_reorder_pics[i]);if (avctx-err_recognition AV_EF_EXPLODE)goto err;}}vps-vps_max_layer_id get_bits(gb, 6);vps-vps_num_layer_sets get_ue_golomb_long(gb) 1;if (vps-vps_num_layer_sets 1 || vps-vps_num_layer_sets 1024 ||(vps-vps_num_layer_sets - 1LL) * (vps-vps_max_layer_id 1LL) get_bits_left(gb)) {av_log(avctx, AV_LOG_ERROR, too many layer_id_included_flags\n);goto err;}for (i 1; i vps-vps_num_layer_sets; i)for (j 0; j vps-vps_max_layer_id; j)skip_bits(gb, 1); // layer_id_included_flag[i][j]vps-vps_timing_info_present_flag get_bits1(gb);if (vps-vps_timing_info_present_flag) {vps-vps_num_units_in_tick get_bits_long(gb, 32);vps-vps_time_scale get_bits_long(gb, 32);vps-vps_poc_proportional_to_timing_flag get_bits1(gb);if (vps-vps_poc_proportional_to_timing_flag)vps-vps_num_ticks_poc_diff_one get_ue_golomb_long(gb) 1;vps-vps_num_hrd_parameters get_ue_golomb_long(gb);if (vps-vps_num_hrd_parameters (unsigned)vps-vps_num_layer_sets) {av_log(avctx, AV_LOG_ERROR,vps_num_hrd_parameters %d is invalid\n, vps-vps_num_hrd_parameters);goto err;}for (i 0; i vps-vps_num_hrd_parameters; i) {int common_inf_present 1;get_ue_golomb_long(gb); // hrd_layer_set_idxif (i)common_inf_present get_bits1(gb);decode_hrd(gb, common_inf_present, vps-hdr[i],vps-vps_max_sub_layers);}}get_bits1(gb); /* vps_extension_flag */if (get_bits_left(gb) 0) {av_log(avctx, AV_LOG_ERROR,Overread VPS by %d bits\n, -get_bits_left(gb));if (ps-vps_list[vps_id])goto err;}if (ps-vps_list[vps_id] !memcmp(ps-vps_list[vps_id], vps, sizeof(*vps))) {ff_refstruct_unref(vps);} else {remove_vps(ps, vps_id);ps-vps_list[vps_id] vps;}return 0;err:ff_refstruct_unref(vps);return AVERROR_INVALIDDATA; }可以看出每个语法元素都能找到对应的一行代码且变量名都完全一样将上述语法描述和代码对应起来看就可以明白这些解析函数代码的含义。
http://www.pierceye.com/news/62187/

相关文章:

  • 企业高端网站建设美工长沙建站网站模板
  • 大连地区建设网站室内设计培训班排行榜
  • 做教务网站的需求分析公司网页制作流程图
  • 英雄联盟网站设计wordpress添加统计
  • 网站直接做标准曲线建网站公司用什么网站程序
  • 清远做网站公司iis wordpress
  • 网站被k还能不能在百度做推广门户网站维护
  • 深圳的网站建设公司排名域名ip查询入口官网
  • 网站 开发 工具网站支持ipv6做哪些改造
  • 上海网站公司珠海网站建设防
  • 兰州房地产网站建设北京网络营销定制
  • 海北高端网站建设公司上海注册公司费用
  • 网站建设网上商城展板设计用什么软件
  • 手机网站可以做公众号凡客和凡客诚品一样吗
  • 手机网站带后台源代码三门峡市住房和城乡建设局网站
  • pc网站建设的优势是什么优化是什么意思?
  • 后盾网原创实战网站建设教程1-15灯具网站模板
  • 给我一个网站2021创意网红
  • wordpress会员制网站wordpress企业建站
  • 58同城做网站的电话网销怎么销售的
  • wordpress 调用站外api无极网站网站
  • 安徽省城乡和建设厅网站微信客户管理系统
  • 福建漳州东山建设局官方网站公司取名大全最新版的
  • 专业轻电商网站建设公司福州网站快速排名提升
  • 网站建设合同定义广点通广告投放平台登录
  • 浙江平湖建设局网站阿里巴巴网站推广怎么做
  • 学校网站的建设论文各类网站推广
  • 昆明凡科建站公司公司网站高端
  • 网站建设与维护ppt模板下载品牌高端网站制作
  • 有个性的个人网站工人找活平台