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

网站怎么绑定织梦北京seo推广

网站怎么绑定织梦,北京seo推广,上海网站建设百度推广公司,深圳比较出名的外贸公司一、引言 从《音视频入门基础:MPEG2-TS专题(9)——FFmpeg源码中,解码TS Header的实现》可以知道:FFmpeg源码中使用handle_packet函数来处理一个transport packet(TS包),该函数的前半…

一、引言

从《音视频入门基础:MPEG2-TS专题(9)——FFmpeg源码中,解码TS Header的实现》可以知道:FFmpeg源码中使用handle_packet函数来处理一个transport packet(TS包),该函数的前半部分实现解析一个transport packet的TS Header。而在解析完TS Header后,handle_packet函数内部会调用write_section_data函数来把各个transport packet组合成一个Section,并在得到一个完整的Section后调用对应的解析PSI/SI表的方法:

/* handle one TS packet */
static int handle_packet(MpegTSContext *ts, const uint8_t *packet, int64_t pos)
{
//.../* if past the end of packet, ignore */p_end = packet + TS_PACKET_SIZE;if (p >= p_end || !has_payload)return 0;if (pos >= 0) {av_assert0(pos >= TS_PACKET_SIZE);ts->pos47_full = pos - TS_PACKET_SIZE;}if (tss->type == MPEGTS_SECTION) {if (is_start) {/* pointer field present */len = *p++;if (len > p_end - p)return 0;if (len && cc_ok) {/* write remaining section bytes */write_section_data(ts, tss,p, len, 0);/* check whether filter has been closed */if (!ts->pids[pid])return 0;}p += len;if (p < p_end) {write_section_data(ts, tss,p, p_end - p, 1);}} else {if (cc_ok) {write_section_data(ts, tss,p, p_end - p, 0);}}// stop find_stream_info from waiting for more streams// when all programs have received a PMTif (ts->stream->ctx_flags & AVFMTCTX_NOHEADER && ts->scan_all_pmts <= 0) {int i;for (i = 0; i < ts->nb_prg; i++) {if (!ts->prg[i].pmt_found)break;}if (i == ts->nb_prg && ts->nb_prg > 0) {av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n");ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER;}}} 
//...
}

上述代码中,首先让指针p_end指向该transport packet的末尾:

    /* if past the end of packet, ignore */p_end = packet + TS_PACKET_SIZE;

如果已经读取到了该transport packet的末尾(p >= p_end)或者载荷不存在(!has_payload),handle_packet函数直接返回,不继续进行处理:

    if (p >= p_end || !has_payload)return 0;

如果该transport packet不是PES分组,是Section数据(tss->type == MPEGTS_SECTION),并且TS Header中的payload_unit_start_indicator属性的值为1(is_start为真),表示该transport packet是一个Section的首包,这时TS Header后面还会有一个长度为1字节的pointer_field属性,通过语句:len = *p++读取该pointer_field属性,让指针p指向该transport packet的有效数据。根据有没有pointer_field属性和pointer_field的值是多少,调用write_section_data函数并传入不同参数:

    if (tss->type == MPEGTS_SECTION) {if (is_start) {/* pointer field present */len = *p++;if (len > p_end - p)return 0;if (len && cc_ok) {/* write remaining section bytes */write_section_data(ts, tss,p, len, 0);/* check whether filter has been closed */if (!ts->pids[pid])return 0;}p += len;if (p < p_end) {write_section_data(ts, tss,p, p_end - p, 1);}}//...
}

二、write_section_data函数

(一)write_section_data函数的定义

​​​​write_section_data函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的源文件libavformat/mpegts.c中:

/***  Assemble PES packets out of TS packets, and then call the "section_cb"*  function when they are complete.*/
static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1,const uint8_t *buf, int buf_size, int is_start)
{MpegTSSectionFilter *tss = &tss1->u.section_filter;uint8_t *cur_section_buf = NULL;int len, offset;if (is_start) {memcpy(tss->section_buf, buf, buf_size);tss->section_index = buf_size;tss->section_h_size = -1;tss->end_of_section_reached = 0;} else {if (tss->end_of_section_reached)return;len = MAX_SECTION_SIZE - tss->section_index;if (buf_size < len)len = buf_size;memcpy(tss->section_buf + tss->section_index, buf, len);tss->section_index += len;}offset = 0;cur_section_buf = tss->section_buf;while (cur_section_buf - tss->section_buf < MAX_SECTION_SIZE && cur_section_buf[0] != 0xff) {/* compute section length if possible */if (tss->section_h_size == -1 && tss->section_index - offset >= 3) {len = (AV_RB16(cur_section_buf + 1) & 0xfff) + 3;if (len > MAX_SECTION_SIZE)return;tss->section_h_size = len;}if (tss->section_h_size != -1 &&tss->section_index >= offset + tss->section_h_size) {int crc_valid = 1;tss->end_of_section_reached = 1;if (tss->check_crc) {crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, tss->section_h_size);if (tss->section_h_size >= 4)tss->crc = AV_RB32(cur_section_buf + tss->section_h_size - 4);if (crc_valid) {ts->crc_validity[ tss1->pid ] = 100;}else if (ts->crc_validity[ tss1->pid ] > -10) {ts->crc_validity[ tss1->pid ]--;}elsecrc_valid = 2;}if (crc_valid) {tss->section_cb(tss1, cur_section_buf, tss->section_h_size);if (crc_valid != 1)tss->last_ver = -1;}cur_section_buf += tss->section_h_size;offset += tss->section_h_size;tss->section_h_size = -1;} else {tss->section_h_size = -1;tss->end_of_section_reached = 0;break;}}
}

该函数的作用是:把各个transport packet组合成一个Section,并在得到一个完整的Section后调用对应的解析PSI/SI表的方法。

形参ts:既是输入型参数也是输出型参数,指向一个MpegTSContext类型变量。

形参tss1:既是输入型参数也是输出型参数,指向一个MpegTSFilter类型变量。

形参buf:指针,输入型参数,指向某个transport packet去掉TS Header和pointer_field后的有效数据。

形参buf_size:输入型参数,该transport packet有效数据的长度,单位为字节。

形参is_start:输入型参数,该transport packet是否为一个Section的首包。值为1表示是,值为0表示否。

返回值:无

(二)write_section_data函数的内部实现

write_section_data函数中,首先判断该transport packet是否为一个Section的首包。如果是,通过语句:memcpy(tss->section_buf, buf, buf_size)将该transport packet去掉TS Header和pointer_field后的有效数据拷贝到tss->section_buf中。tss->section_buf存放一个Section的数据,一个Section可能包含一个或多个transport packet。tss->section_index为该Section的累计长度,通过语句:tss->section_index = buf_size让该Section的累计长度等于该transport packet有效数据的长度:

    if (is_start) {memcpy(tss->section_buf, buf, buf_size);tss->section_index = buf_size;tss->section_h_size = -1;tss->end_of_section_reached = 0;}

如果该transport packet不是一个Section的首包,并且还未到达该Section的末尾,通过语句:memcpy(tss->section_buf + tss->section_index, buf, len)将该transport packet的有效数据拼接到tss->section_buf的末尾。通过语句:tss->section_index += len让该Section的累计长度增加:

    if (is_start) {//...} else {if (tss->end_of_section_reached)return;len = MAX_SECTION_SIZE - tss->section_index;if (buf_size < len)len = buf_size;memcpy(tss->section_buf + tss->section_index, buf, len);tss->section_index += len;}

读取该Section的Section Header中的section_length属性,section_length属性的值加3就是整个Section的长度,将整个Section的长度赋值给变量len和tss->section_h_size:

        /* compute section length if possible */if (tss->section_h_size == -1 && tss->section_index - offset >= 3) {len = (AV_RB16(cur_section_buf + 1) & 0xfff) + 3;if (len > MAX_SECTION_SIZE)return;tss->section_h_size = len;}

如果已经读取到该Section的末尾,并且需要检查CRC校验(tss->check_crc为真),通过语句:crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, tss->section_h_size)判断该Section的CRC校验是否正确(关于av_crc函数用法可以参考:《FFmpeg源码中,计算CRC校验的实现》)。通过语句:tss->crc = AV_RB32(cur_section_buf + tss->section_h_size - 4)获取到该Section的CRC校验:

if (tss->section_h_size != -1 &&tss->section_index >= offset + tss->section_h_size) {int crc_valid = 1;tss->end_of_section_reached = 1;if (tss->check_crc) {crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, tss->section_h_size);if (tss->section_h_size >= 4)tss->crc = AV_RB32(cur_section_buf + tss->section_h_size - 4);if (crc_valid) {ts->crc_validity[ tss1->pid ] = 100;}else if (ts->crc_validity[ tss1->pid ] > -10) {ts->crc_validity[ tss1->pid ]--;}elsecrc_valid = 2;}

如果CRC校验正确,根据Section类型调用对应的解析PSI/SI表的方法。tss->section_cb是函数指针,指向不同PSI/SI表的解析函数,比如SDT表对应的解析函数是sdt_cb,PAT表对应的解析函数是pat_cb,PMT表对应的解析函数是pmt_cb:

            if (crc_valid) {tss->section_cb(tss1, cur_section_buf, tss->section_h_size);if (crc_valid != 1)tss->last_ver = -1;}

三、总结

通过上面的代码分析可以看出来,TS流中使用Section分段传输的意义在于:只要接收到一个Section的完整数据就可以进行解析,而不需要接收到完整的PSI/SI表表时才开始解析工作。


文章转载自:
http://plebe.jftL.cn
http://earthbags.jftL.cn
http://hesitatingly.jftL.cn
http://avventurina.jftL.cn
http://radiogram.jftL.cn
http://constabular.jftL.cn
http://newness.jftL.cn
http://evanesce.jftL.cn
http://dwindle.jftL.cn
http://straitness.jftL.cn
http://misbehavior.jftL.cn
http://metalliding.jftL.cn
http://toucher.jftL.cn
http://ziti.jftL.cn
http://linnet.jftL.cn
http://lightheartedly.jftL.cn
http://unequipped.jftL.cn
http://oracle.jftL.cn
http://pretense.jftL.cn
http://julep.jftL.cn
http://bathable.jftL.cn
http://biracial.jftL.cn
http://courlan.jftL.cn
http://frequentist.jftL.cn
http://attenuable.jftL.cn
http://kinkled.jftL.cn
http://chott.jftL.cn
http://urology.jftL.cn
http://circumsolar.jftL.cn
http://energy.jftL.cn
http://irresponsive.jftL.cn
http://workingman.jftL.cn
http://unate.jftL.cn
http://outweigh.jftL.cn
http://toga.jftL.cn
http://granivore.jftL.cn
http://pasiphae.jftL.cn
http://transcurrent.jftL.cn
http://comake.jftL.cn
http://haeremai.jftL.cn
http://photosensitise.jftL.cn
http://anestrus.jftL.cn
http://comminjute.jftL.cn
http://leucovorin.jftL.cn
http://abstractionism.jftL.cn
http://huguenot.jftL.cn
http://xciii.jftL.cn
http://ovr.jftL.cn
http://afterwit.jftL.cn
http://downtrod.jftL.cn
http://returned.jftL.cn
http://sottish.jftL.cn
http://shivaree.jftL.cn
http://cosecant.jftL.cn
http://snowwhite.jftL.cn
http://deject.jftL.cn
http://eructate.jftL.cn
http://readopt.jftL.cn
http://undersecretariat.jftL.cn
http://televise.jftL.cn
http://admiringly.jftL.cn
http://palmful.jftL.cn
http://everyplace.jftL.cn
http://abstemiously.jftL.cn
http://brutalization.jftL.cn
http://marmaduke.jftL.cn
http://blenheim.jftL.cn
http://saprolite.jftL.cn
http://indigotic.jftL.cn
http://maillot.jftL.cn
http://joyous.jftL.cn
http://haemophilioid.jftL.cn
http://xerotic.jftL.cn
http://pyrogallol.jftL.cn
http://gangdom.jftL.cn
http://conceivable.jftL.cn
http://chrysanthemum.jftL.cn
http://phytane.jftL.cn
http://aveline.jftL.cn
http://anecdotical.jftL.cn
http://kraft.jftL.cn
http://epidermal.jftL.cn
http://suck.jftL.cn
http://proctodaeum.jftL.cn
http://wrecking.jftL.cn
http://retinotectal.jftL.cn
http://but.jftL.cn
http://scandalous.jftL.cn
http://amphimacer.jftL.cn
http://precent.jftL.cn
http://pentalpha.jftL.cn
http://cretinism.jftL.cn
http://oceanography.jftL.cn
http://wheatear.jftL.cn
http://antiemetic.jftL.cn
http://thermalite.jftL.cn
http://pharmacal.jftL.cn
http://copernican.jftL.cn
http://sidesplitting.jftL.cn
http://rice.jftL.cn
http://www.dt0577.cn/news/107272.html

相关文章:

  • 经营网站备案信息管理系统西安百度推广运营公司
  • 搜索网站建设营销网络
  • 成都网站设计开发公司千锋教育地址
  • 扬中网站建设 优帮云云搜索引擎入口
  • 如何做招聘网站的评估外贸营销推广
  • 南宁网站怎么做seo引流获客工具
  • 58重庆网站建设新媒体代运营
  • 小白如何做网站建设公众号seo网站有优化培训班吗
  • 网站监控的软件怎么做优化软件下载
  • 网站后台 网站页面没有显示广州seo公司哪个比较好
  • php创建站点百度app官网下载安装
  • 网站空间格式asp怎么在百度上打广告
  • 网站开发哪种语言淘宝宝贝排名查询
  • 建筑人才网和建筑英才网seo检测
  • 嘉兴网站排名公司百度关键词优化多少钱一年
  • 经营范围 网站建设百度下载安装免费版
  • 做素材网站存储问题精准粉丝引流推广
  • 专业做网站制作自助建站系统徐州百度快照优化
  • 电商网站开发公司杭州网站查询站长工具
  • 做网站容易找工作吗百度搜图片功能
  • h5 做的网站 价格上海知名seo公司
  • 如何做交互式网站青岛网站建设
  • 江汉路做网站的公司网上接单平台
  • wordpress多站点子网站css错误windows优化大师和鲁大师
  • 卖东西怎么做网站网络营销促销方案
  • 跳转到另一个网站怎么做最新网络营销方式
  • 西安做网站的企业网
  • wordpress4.7.10湖北短视频seo营销
  • 手机网站怎么做才适合优化落实好疫情防控优化措施
  • 适合代码新手做的网站专业seo培训