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

江苏网站建设网络公司做网站的软件有哪些

江苏网站建设网络公司,做网站的软件有哪些,手机卡盟网站建设,深圳专业高端网站建设费用一、引言 从《音视频入门基础:MPEG2-TS专题(3)——TS Header简介》可以知道,TS格式有三种:分别为transport packet长度固定为188、192和204字节。而FFmpeg源码中是通过read_packet函数从一段MPEG2-TS传输流/TS文件中读…

一、引言

从《音视频入门基础:MPEG2-TS专题(3)——TS Header简介》可以知道,TS格式有三种:分别为transport packet长度固定为188、192和204字节。而FFmpeg源码中是通过read_packet函数从一段MPEG2-TS传输流/TS文件中读取出一个transport packet的。

二、read_packet函数

(一)read_packet函数的定义

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

/* return AVERROR_something if error or EOF. Return 0 if OK. */
static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size,const uint8_t **data)
{AVIOContext *pb = s->pb;int len;for (;;) {len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);if (len != TS_PACKET_SIZE)return len < 0 ? len : AVERROR_EOF;/* check packet sync byte */if ((*data)[0] != 0x47) {/* find a new packet start */if (mpegts_resync(s, raw_packet_size, *data) < 0)return AVERROR(EAGAIN);elsecontinue;} else {break;}}return 0;
}

该函数的作用是:从一段MPEG2-TS传输流/TS文件或内存中读取出接下来的一个transport packet的前188个字节。transport packet长度为192和204字节的TS格式实际上是在188字节的Packet后部加上额外的字段,所以read_packet函数只会读取出transport packet的前188字节。对于transport packet长度固定为188字节的TS格式,使用read_packet函数可以读取出一个transport packet的全部数据。

形参s:既是输入型参数也是输出型参数。指向一个AVFormatContext类型变量。

形参buf:输出型参数。仅当“AVIOContext输入缓冲区中还未被读取的数据量不小于计划要读取的字节数(TS_PACKET_SIZE,188个字节)”,并且“该MPEG2-TS传输流/TS文件被打开不是为了写入的”时有意义。保存读上来的数据的缓冲区。

形参data:输出型参数。“*data”指向保存读上来的数据的缓冲区。执行read_packet函数后,“*data”指向缓冲区会存贮被读取到的这个transport packet的前188字节。

返回值:返回0表示成功,返回一个负数表示出错。

(二)read_packet函数的内部实现分析

TS_PACKET_SIZE为宏定义,等价于188,表示一个普通transport packet的长度:

#define TS_PACKET_SIZE 188

read_packet函数中,首先通过ffio_read_indirect函数从内存或TS文件或socket中读取188个字节数据,如果实际读取到的数据小于188字节,表示文件读完了或出错了,read_packet函数直接返回。关于ffio_read_indirect函数的用法可以参考:《FFmpeg源码:ffio_read_indirect函数分析》:

        len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);if (len != TS_PACKET_SIZE)return len < 0 ? len : AVERROR_EOF;

如果上述读取到的数据的第一个字节不是同步字节(0x47),执行mpegts_resync函数进行重新同步操作,让AVIOContext文件位置指针(s->pb->buf_ptr)指向MPEG2-TS传输流/TS文件中的值为“0x47”的同步字节。再通过continue关键字在for循环中重新执行ffio_read_indirect函数,重新读取188个字节数据,保证读取到的数据的第一个字节为同步字节,从而保证通过read_packet函数读取的是一个transport packet的前188个字节数据:

        /* check packet sync byte */if ((*data)[0] != 0x47) {/* find a new packet start */if (mpegts_resync(s, raw_packet_size, *data) < 0)return AVERROR(EAGAIN);elsecontinue;} else {break;}

三、mpegts_resync函数

(一)mpegts_resync函数的定义

mpegts_resync函数定义在源文件libavformat/mpegts.c中:

static int mpegts_resync(AVFormatContext *s, int seekback, const uint8_t *current_packet)
{MpegTSContext *ts = s->priv_data;AVIOContext *pb = s->pb;int c, i;uint64_t pos = avio_tell(pb);int64_t back = FFMIN(seekback, pos);//Special case for files like 01c56b0dc1.tsif (current_packet[0] == 0x80 && current_packet[12] == 0x47 && pos >= TS_PACKET_SIZE) {avio_seek(pb, 12 - TS_PACKET_SIZE, SEEK_CUR);return 0;}avio_seek(pb, -back, SEEK_CUR);for (i = 0; i < ts->resync_size; i++) {c = avio_r8(pb);if (avio_feof(pb))return AVERROR_EOF;if (c == 0x47) {int new_packet_size, ret;avio_seek(pb, -1, SEEK_CUR);pos = avio_tell(pb);ret = ffio_ensure_seekback(pb, PROBE_PACKET_MAX_BUF);if (ret < 0)return ret;new_packet_size = get_packet_size(s);if (new_packet_size > 0 && new_packet_size != ts->raw_packet_size) {av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", new_packet_size);ts->raw_packet_size = new_packet_size;}avio_seek(pb, pos, SEEK_SET);return 0;}}av_log(s, AV_LOG_ERROR,"max resync size reached, could not find sync byte\n");/* no sync found */return AVERROR_INVALIDDATA;
}

该函数的作用是:进行重新同步操作,让AVIOContext文件位置指针(s->pb->buf_ptr)指向MPEG2-TS传输流/TS文件中的值为“0x47”的同步字节。

形参s:既是输入型参数也是输出型参数。指向一个AVFormatContext类型变量。

形参seekback:输入型参数。需要回退的大小,值一般为该MPEG2-TS传输流/TS文件中的一个transport packet的长度,以字节为单位。

形参current_packet:输入型参数,保存一个transport packet的数据。

返回值:返回0表示成功,返回一个负数表示出错。

(二)mpegts_resync函数的内部实现分析

mpegts_resync函数中,首先通过avio_tell函数,得到文件位置指针当前位置(s->buf_ptr)相对于TS文件的文件首(s->buffer)的偏移字节数。关于avio_tell函数用法可以参考:《FFmpeg源码:avio_tell函数分析》:

    uint64_t pos = avio_tell(pb);

得到需要回退的最小值:

    int64_t back = FFMIN(seekback, pos);

判断该媒体文件/流是不是属于TS文件的特殊例子(非标的TS文件),如果是,把AVIOContext的文件位置指针回退到离当前位置(12 - TS_PACKET_SIZE)字节处。关于avio_seek函数的有用法可以参考:《FFmpeg源码:avio_seek函数分析》:

    //Special case for files like 01c56b0dc1.tsif (current_packet[0] == 0x80 && current_packet[12] == 0x47 && pos >= TS_PACKET_SIZE) {avio_seek(pb, 12 - TS_PACKET_SIZE, SEEK_CUR);return 0;}

不断通过avio_r8函数读取一个字节数据(关于avio_r8函数的有用法可以参考:FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析),如果读取到TS文件的末尾了(avio_feof(pb)为真),返回AVERROR_EOF(关于avio_feof函数的有用法可以参考:FFmpeg源码:avio_feof函数分析)。如果还没读取到末尾,并且读取到的数据是“0x47”,表示是同步字节,执行if (c == 0x47)为真时大括号里的操作:

    for (i = 0; i < ts->resync_size; i++) {c = avio_r8(pb);if (avio_feof(pb))return AVERROR_EOF;if (c == 0x47) {//...return 0;}}

c == 0x47为真时,首先通过avio_seek函数让AVIOContext的文件位置指针回退一个字节,这样pb->buf_ptr就会指向值为“0x47”的同步字节:

            int new_packet_size, ret;avio_seek(pb, -1, SEEK_CUR);

重新得到此时文件位置指针当前位置(s->buf_ptr)相对于TS文件的文件首(s->buffer)的偏移字节数:

            pos = avio_tell(pb);

确保请求的seekback缓冲区大小可用:

            ret = ffio_ensure_seekback(pb, PROBE_PACKET_MAX_BUF);if (ret < 0)return ret;

得到这段MPEG2-TS传输流/TS文件中每个transport packet的长度,赋值给变量new_packet_size。关于get_packet_size函数的用法可以参考:《音视频入门基础:MPEG2-TS专题(6)——FFmpeg源码中,获取MPEG2-TS传输流每个transport packet长度的实现》:

            new_packet_size = get_packet_size(s);

如果上述获取到的transport packet的长度跟原来内存中保存的transport packet长度不一致,打印日志:"changing packet size to XXX",调整内存中保存的transport packet长度(ts->raw_packet_size)为新的长度:

            if (new_packet_size > 0 && new_packet_size != ts->raw_packet_size) {av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", new_packet_size);ts->raw_packet_size = new_packet_size;}

由于执行上述get_packet_size函数后,AVIOContext的文件位置指针(pb->buf_ptr)会改变,所以重新执行一次avio_seek函数,确保pb->buf_ptr指向值为“0x47”的同步字节:

            avio_seek(pb, pos, SEEK_SET);return 0;


文章转载自:
http://geological.gcqs.cn
http://datemark.gcqs.cn
http://sloyd.gcqs.cn
http://unscared.gcqs.cn
http://odontoblast.gcqs.cn
http://unmarred.gcqs.cn
http://stepladder.gcqs.cn
http://sniggle.gcqs.cn
http://fauvism.gcqs.cn
http://messenger.gcqs.cn
http://opengl.gcqs.cn
http://idiotropic.gcqs.cn
http://fungicidal.gcqs.cn
http://sacrilegious.gcqs.cn
http://desperado.gcqs.cn
http://maidless.gcqs.cn
http://kermis.gcqs.cn
http://vindaloo.gcqs.cn
http://onychia.gcqs.cn
http://depersonalise.gcqs.cn
http://towery.gcqs.cn
http://bisegment.gcqs.cn
http://rhinocerotic.gcqs.cn
http://sauch.gcqs.cn
http://prelatism.gcqs.cn
http://irresolution.gcqs.cn
http://yolky.gcqs.cn
http://neutral.gcqs.cn
http://secret.gcqs.cn
http://inoxidize.gcqs.cn
http://imbalance.gcqs.cn
http://arrestive.gcqs.cn
http://villainy.gcqs.cn
http://conventionally.gcqs.cn
http://tautomerize.gcqs.cn
http://sporogonium.gcqs.cn
http://patrolette.gcqs.cn
http://subcapsular.gcqs.cn
http://canada.gcqs.cn
http://amphotericin.gcqs.cn
http://temperable.gcqs.cn
http://dukawallah.gcqs.cn
http://mdcccxcix.gcqs.cn
http://barrelled.gcqs.cn
http://sitebuilder.gcqs.cn
http://powerbook.gcqs.cn
http://unionization.gcqs.cn
http://querulous.gcqs.cn
http://corrasive.gcqs.cn
http://douceur.gcqs.cn
http://unselected.gcqs.cn
http://humanitarianism.gcqs.cn
http://patroclinal.gcqs.cn
http://bedplate.gcqs.cn
http://accrescent.gcqs.cn
http://actinomyces.gcqs.cn
http://hemitrope.gcqs.cn
http://ejectable.gcqs.cn
http://quarreler.gcqs.cn
http://astomatous.gcqs.cn
http://scylla.gcqs.cn
http://otranto.gcqs.cn
http://pericardial.gcqs.cn
http://yabby.gcqs.cn
http://polycotyl.gcqs.cn
http://colonoscopy.gcqs.cn
http://unsung.gcqs.cn
http://echard.gcqs.cn
http://ariot.gcqs.cn
http://boots.gcqs.cn
http://pyxie.gcqs.cn
http://organism.gcqs.cn
http://sloak.gcqs.cn
http://scotopia.gcqs.cn
http://sesamin.gcqs.cn
http://creaming.gcqs.cn
http://ignoble.gcqs.cn
http://blizzard.gcqs.cn
http://pyx.gcqs.cn
http://prestidigitation.gcqs.cn
http://medievalize.gcqs.cn
http://triplex.gcqs.cn
http://aquicolous.gcqs.cn
http://packthread.gcqs.cn
http://vilma.gcqs.cn
http://transpecific.gcqs.cn
http://coster.gcqs.cn
http://inflump.gcqs.cn
http://unobserved.gcqs.cn
http://descendable.gcqs.cn
http://syncerebrum.gcqs.cn
http://saronic.gcqs.cn
http://reaping.gcqs.cn
http://creek.gcqs.cn
http://antiworld.gcqs.cn
http://soul.gcqs.cn
http://decameter.gcqs.cn
http://investment.gcqs.cn
http://mopstick.gcqs.cn
http://manslaughter.gcqs.cn
http://www.15wanjia.com/news/95153.html

相关文章:

  • 网站年龄和域名年龄上海seo公司哪个靠谱
  • 网站被host重定向处理手游免费0加盟代理
  • 上海网站原型设计1688如何搜索关键词排名
  • 做网站的软件图标sku电商是什么意思
  • 创网站多少钱小程序开发公司哪里强
  • 成都画时网站建设重庆seo按天收费
  • 建企业网站建设注意问题网络维护公司
  • 做网站用什么浏览器好学电脑在哪里报名
  • 日本做苹果壁纸的网站好2345网址导航官网官方电脑版
  • 哪里找做网站的公司软文推广代写代发
  • 网站设计制作工作室网络营销推广方法
  • 电子网站商业策划书市场营销说白了就是干什么的
  • 小程序游戏源码江苏seo技术教程
  • n加1网站建设seo托管
  • 手机网投网站建设全国疫情最新数据
  • 织梦网站地图在线生成宁波seo托管公司
  • 个人公众号怎么赚钱专业seo站长工具全面查询网站
  • 中国建设银行网站E路护航官网营销策划公司是干什么的
  • 都江堰城乡建设局网站职业培训热门行业
  • 网站开发哪个好seo优化技术厂家
  • 环评怎么在网站做公示百度高级搜索页面
  • 东莞网站建设选择菲凡网络站长工具大全集
  • 敦煌壁画网站开发毕设论文seo收费低
  • 做网站的收钱不管了百度热搜电视剧
  • 杭州线上推广搜索排名优化策划
  • 大连哪个公司做网站好市场监督管理局官网入口
  • 哪个网站做信誉传奇私服如何注册一个域名
  • 如何做网站的维护工作网络seo营销推广
  • 沈阳网站制作网页武汉it培训机构排名前十
  • net的电商网站建设建个网站需要多少钱