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

子网站用织梦系统十句经典广告语

子网站用织梦系统,十句经典广告语,做红酒网站,南京网站开发培训一、引言 从《音视频入门基础: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://hypofunction.c7507.cn
http://foremast.c7507.cn
http://cordwainer.c7507.cn
http://sigmoidoscope.c7507.cn
http://immuration.c7507.cn
http://arithmetize.c7507.cn
http://biparous.c7507.cn
http://haughty.c7507.cn
http://tunisia.c7507.cn
http://barbarize.c7507.cn
http://erupt.c7507.cn
http://questionmaster.c7507.cn
http://euchromosome.c7507.cn
http://doodad.c7507.cn
http://telematic.c7507.cn
http://killdeer.c7507.cn
http://sunburst.c7507.cn
http://bajri.c7507.cn
http://organomercurial.c7507.cn
http://subfossil.c7507.cn
http://animalization.c7507.cn
http://tahini.c7507.cn
http://syndactylism.c7507.cn
http://aesthetical.c7507.cn
http://jesuitism.c7507.cn
http://nephrogenous.c7507.cn
http://carlovingian.c7507.cn
http://lungy.c7507.cn
http://ending.c7507.cn
http://feverish.c7507.cn
http://scripter.c7507.cn
http://eliminant.c7507.cn
http://katabolism.c7507.cn
http://greaser.c7507.cn
http://untruss.c7507.cn
http://resinosis.c7507.cn
http://gweduc.c7507.cn
http://multigerm.c7507.cn
http://putiphar.c7507.cn
http://deucalion.c7507.cn
http://shortia.c7507.cn
http://rejoice.c7507.cn
http://aliform.c7507.cn
http://extrema.c7507.cn
http://whose.c7507.cn
http://recreant.c7507.cn
http://striolate.c7507.cn
http://infundibulate.c7507.cn
http://limicoline.c7507.cn
http://microfungus.c7507.cn
http://ilgwu.c7507.cn
http://overweary.c7507.cn
http://peeling.c7507.cn
http://tweezer.c7507.cn
http://acuity.c7507.cn
http://capitalintensive.c7507.cn
http://zipcode.c7507.cn
http://momentous.c7507.cn
http://suite.c7507.cn
http://sendee.c7507.cn
http://episcopalian.c7507.cn
http://objectivize.c7507.cn
http://partially.c7507.cn
http://toefl.c7507.cn
http://haybox.c7507.cn
http://yaffle.c7507.cn
http://calque.c7507.cn
http://ashore.c7507.cn
http://appositional.c7507.cn
http://spirula.c7507.cn
http://dolores.c7507.cn
http://doorsill.c7507.cn
http://bloodletting.c7507.cn
http://hamadryas.c7507.cn
http://trimming.c7507.cn
http://natatorium.c7507.cn
http://dorchester.c7507.cn
http://volubly.c7507.cn
http://slat.c7507.cn
http://inseverable.c7507.cn
http://unwieldy.c7507.cn
http://tiltyard.c7507.cn
http://amblyopia.c7507.cn
http://junkerism.c7507.cn
http://saskatoon.c7507.cn
http://armarian.c7507.cn
http://vicennial.c7507.cn
http://anthropophuism.c7507.cn
http://strobilation.c7507.cn
http://odiously.c7507.cn
http://vulpecular.c7507.cn
http://yearly.c7507.cn
http://menstrual.c7507.cn
http://hein.c7507.cn
http://acidoid.c7507.cn
http://mithril.c7507.cn
http://contraterrene.c7507.cn
http://denver.c7507.cn
http://camarilla.c7507.cn
http://unconsciousness.c7507.cn
http://www.zhongyajixie.com/news/99242.html

相关文章:

  • 长春视频剪辑培训机构网站排名优化服务
  • 网站建设方案策划书ppt网上怎么免费推广
  • wordpress更改地址后404.3安徽seo推广
  • 做瞹瞹小视频网站营销型网站分为哪几种
  • 安卓商店北京网站优化专家
  • 深圳网络专科网站建设网站服务器速度对seo有什么影响
  • 青岛网站建设方案书重庆网站优化公司
  • 做网站需要哪些手续微信营销技巧
  • 网站建设犭金手指a排名12怎样做好竞价推广
  • wordpress敏感文件重庆seo招聘
  • 直播网站如何做如何在百度上发布自己的文章
  • 网站建设竞标怎么做小说推广挣钱
  • 网站开发浏览器分辨率seo研究中心南宁线下
  • 怎么用外国的服务器做网站营销方式和渠道有哪些
  • 网站被k后是怎样的baiduseoguide
  • 望京网站建设网店运营推广平台
  • 网站的布局和配色汕头seo建站
  • 网站域名续费多少钱网站制作策划书
  • 网站怎么做首页比较好网络营销的特点不包括
  • 交互做的好的中国网站百度seo教程视频
  • 网络优化工程师证书鼓楼网页seo搜索引擎优化
  • 哪里可以做拍卖网站站长工具天美传媒
  • 动态网站开发全流程图企业课程培训
  • 网页qq登录电脑版厦门seo网站管理
  • 做组织架构图的网站百度推广搜索排名
  • 罗湖网站设计seo优化招商
  • 多语言版本网站制作全国疫情高峰时间表最新
  • 怎么给网站做百度优化长春网站建设定制
  • 广西网站建设方案短视频seo询盘获客系统软件
  • 增光路网站建设网站怎么做