中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

濟(jì)南網(wǎng)站建設(shè)公網(wǎng)絡(luò)服務(wù)

濟(jì)南網(wǎng)站建設(shè)公,網(wǎng)絡(luò)服務(wù),bootstrap手機(jī)網(wǎng)站模板,深圳企業(yè)網(wǎng)站建設(shè)公司一、引言 通過FFmpeg命令: ./ffmpeg -i XXX.ts 可以判斷出某個(gè)文件是否為TS文件: 所以FFmpeg是怎樣判斷出某個(gè)文件是否為TS文件呢?它內(nèi)部其實(shí)是通過mpegts_probe函數(shù)來判斷的。從《FFmpeg源碼:av_probe_input_format3函數(shù)和AVI…

一、引言

通過FFmpeg命令:

./ffmpeg -i XXX.ts

可以判斷出某個(gè)文件是否為TS文件:

所以FFmpeg是怎樣判斷出某個(gè)文件是否為TS文件呢?它內(nèi)部其實(shí)是通過mpegts_probe函數(shù)來判斷的。從《FFmpeg源碼:av_probe_input_format3函數(shù)和AVInputFormat結(jié)構(gòu)體分析(FFmpeg源碼5.0.3版本)》和《7.0.1版本的FFmpeg源碼中av_probe_input_format3函數(shù)和AVInputFormat結(jié)構(gòu)體的改變》中可以知道:FFmpeg源碼中實(shí)現(xiàn)容器格式檢測的函數(shù)是av_probe_input_format3函數(shù),其內(nèi)部通過循環(huán)while ((fmt1 = av_demuxer_iterate(&i))) 拿到所有容器格式對應(yīng)的AVInputFormat結(jié)構(gòu),然后通過score = fmt1->read_probe(&lpd)語句執(zhí)行不同容器格式對應(yīng)的解析函數(shù),根據(jù)是否能被解析,以及匹配程度,來判斷出這是哪種容器格式。而TS文件對應(yīng)的解析函數(shù)就是mpegts_probe函數(shù)。

二、mpegts_probe函數(shù)的定義

mpegts_probe函數(shù)定義在FFmpeg源碼(本文演示用的FFmpeg源碼版本為7.0.1)的源文件libavformat/mpegts.c中:

static int mpegts_probe(const AVProbeData *p)
{const int size = p->buf_size;int maxscore = 0;int sumscore = 0;int i;int check_count = size / TS_FEC_PACKET_SIZE;
#define CHECK_COUNT 10
#define CHECK_BLOCK 100if (!check_count)return 0;for (i = 0; i<check_count; i+=CHECK_BLOCK) {int left = FFMIN(check_count - i, CHECK_BLOCK);int score      = analyze(p->buf + TS_PACKET_SIZE     *i, TS_PACKET_SIZE     *left, TS_PACKET_SIZE     , 1);int dvhs_score = analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, 1);int fec_score  = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , 1);score = FFMAX3(score, dvhs_score, fec_score);sumscore += score;maxscore = FFMAX(maxscore, score);}sumscore = sumscore * CHECK_COUNT / check_count;maxscore = maxscore * CHECK_COUNT / CHECK_BLOCK;ff_dlog(0, "TS score: %d %d\n", sumscore, maxscore);if        (check_count > CHECK_COUNT && sumscore > 6) {return AVPROBE_SCORE_MAX   + sumscore - CHECK_COUNT;} else if (check_count >= CHECK_COUNT && sumscore > 6) {return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;} else if (check_count >= CHECK_COUNT && maxscore > 6) {return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;} else if (sumscore > 6) {return 2;} else {return 0;}
}

該函數(shù)的作用就是檢測某個(gè)文件是否為TS文件。

形參p:輸入型參數(shù),為AVProbeData類型的指針。

AVProbeData結(jié)構(gòu)體聲明在libavformat/avformat.h中:

/*** This structure contains the data a format has to probe a file.*/
typedef struct AVProbeData {const char *filename;unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */int buf_size;       /**< Size of buf except extra allocated bytes */const char *mime_type; /**< mime_type, when known. */
} AVProbeData;

p->filename為:需要被推測格式的文件的路徑。

p->buf:指向“存放從路徑為p->filename的TS文件中讀取出來的二進(jìn)制數(shù)據(jù)”的緩沖區(qū)。

p->buf_size:緩沖區(qū)p->buf的大小,單位為字節(jié)。注:FFmpeg判斷某個(gè)文件的格式時(shí)不會讀取完整個(gè)文件,只會讀取它前面的一部分,比如最開始的2048個(gè)字節(jié)。只要根據(jù)前面的這些字節(jié)就足夠判斷出它的格式了,所以p->buf_size的值一般就是2048。

p->mime_type:一般為NULL,可忽略。

返回值:返回一個(gè)類型為整形的分值。返回0表示該文件完全不符合TS格式。返回的值越接近100表示該文件越符合TS格式。

三、analyze函數(shù)的定義

mpegts_probe函數(shù)中,會調(diào)用analyze函數(shù),analyze函數(shù)定義如下:

static int analyze(const uint8_t *buf, int size, int packet_size,int probe)
{int stat[TS_MAX_PACKET_SIZE];int stat_all = 0;int i;int best_score = 0;memset(stat, 0, packet_size * sizeof(*stat));for (i = 0; i < size - 3; i++) {if (buf[i] == 0x47) {int pid = AV_RB16(buf+1) & 0x1FFF;int asc = buf[i + 3] & 0x30;if (!probe || pid == 0x1FFF || asc) {int x = i % packet_size;stat[x]++;stat_all++;if (stat[x] > best_score) {best_score = stat[x];}}}}return best_score - FFMAX(stat_all - 10*best_score, 0)/10;
}

該函數(shù)的作用是:檢測buf指向的碼流的前size個(gè)字節(jié),檢測其是否符合每個(gè)transport packet(又稱TS包,TS分組、傳輸流報(bào)文)的長度固定為packet_size個(gè)字節(jié)的TS格式。返回一個(gè)類型為整形的分值,返回的值越接近100表示越符合對應(yīng)的TS格式。

從《音視頻入門基礎(chǔ):MPEG2-TS專題(3)——TS Header簡介》可以知道,TS格式有三種:分別為transport packet長度固定為188、192和204字節(jié)。

analyze函數(shù)中首先會定義一個(gè)元素個(gè)數(shù)為TS_MAX_PACKET_SIZE(值為204)的數(shù)組stat。因?yàn)榧由狭薋EC前向糾錯的情況下,一個(gè)transport packet長度為204字節(jié);而普通的MPEG2-TS傳輸流中,一個(gè)transport packet長度固定為188字節(jié)。所以一個(gè)transport packet的最大長度為204字節(jié),所以定義數(shù)組stat的元素個(gè)數(shù)為TS_MAX_PACKET_SIZE(值為204字節(jié)):

    int stat[TS_MAX_PACKET_SIZE];int stat_all = 0;int i;int best_score = 0;memset(stat, 0, packet_size * sizeof(*stat));

判斷是否讀取到了值為0x47的同步字節(jié):

if (buf[i] == 0x47)

如果讀取到了同步字節(jié),讀取TS Header中的PID屬性,賦值給變量pid;讀取TS Header中的adaptation_field_control屬性,將該屬性的值經(jīng)過運(yùn)算,賦值給變量asc:

            int pid = AV_RB16(buf+1) & 0x1FFF;int asc = buf[i + 3] & 0x30;

如果不是探測格式(!probe)或該transport packet為空包(pid == 0x1FFF)或適配域存在標(biāo)志大于0(asc),通過取余運(yùn)算,判斷對應(yīng)的二進(jìn)制數(shù)據(jù)是否符合transport packet長度為packet_size個(gè)字節(jié)的TS格式:

            if (!probe || pid == 0x1FFF || asc) {int x = i % packet_size;stat[x]++;stat_all++;if (stat[x] > best_score) {best_score = stat[x];}}

不斷循環(huán),每符合一次“transport packet長度為packet_size個(gè)字節(jié)”的條件時(shí),就讓分值累加。最后返回最終得到的分值,該分值表示符合對應(yīng)的TS格式的程度:

    for (i = 0; i < size - 3; i++) {//...}return best_score - FFMAX(stat_all - 10*best_score, 0)/10;

四、mpegts_probe函數(shù)的內(nèi)部實(shí)現(xiàn)分析

宏TS_FEC_PACKET_SIZE、TS_DVHS_PACKET_SIZE、TS_PACKET_SIZE定義如下,分別對應(yīng)transport packet長度固定為188、192和204字節(jié)的TS格式:

#define TS_FEC_PACKET_SIZE 204
#define TS_DVHS_PACKET_SIZE 192
#define TS_PACKET_SIZE 188
#define TS_MAX_PACKET_SIZE 204

mpegts_probe函數(shù)中會調(diào)用analyze函數(shù)。從上面對analyze函數(shù)的分析,我們可以知道:

1.語句int score = analyze(p->buf + TS_PACKET_SIZE ? ? *i, TS_PACKET_SIZE ? ? *left, TS_PACKET_SIZE ? ? , 1)的作用是:檢測“p->buf + TS_PACKET_SIZE*i”指向的碼流符合transport packet長度固定為188字節(jié)的TS格式的程度,將對應(yīng)的分?jǐn)?shù)賦值給變量score。

2.語句int dvhs_score = analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, 1)的作用是:檢測“p->buf + TS_DVHS_PACKET_SIZE*i”指向的碼流符合transport packet長度固定為192字節(jié)的TS格式的程度,將對應(yīng)的分?jǐn)?shù)賦值給變量dvhs_score 。

3.語句int fec_score ?= analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , 1)的作用是:檢測“p->buf + TS_FEC_PACKET_SIZE *i”指向的碼流符合transport packet長度固定為204字節(jié)的TS格式的程度,將對應(yīng)的分?jǐn)?shù)賦值給變量fec_score ?:

        int score      = analyze(p->buf + TS_PACKET_SIZE     *i, TS_PACKET_SIZE     *left, TS_PACKET_SIZE     , 1);int dvhs_score = analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, 1);int fec_score  = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , 1);

取變量score、dvhs_score、fec_score的最大值,即該碼流最符合的那種TS格式的分?jǐn)?shù),賦值給變量score:

        score = FFMAX3(score, dvhs_score, fec_score);sumscore += score;maxscore = FFMAX(maxscore, score);

返回最終表示符合程度的分?jǐn)?shù):

    sumscore = sumscore * CHECK_COUNT / check_count;maxscore = maxscore * CHECK_COUNT / CHECK_BLOCK;ff_dlog(0, "TS score: %d %d\n", sumscore, maxscore);if        (check_count > CHECK_COUNT && sumscore > 6) {return AVPROBE_SCORE_MAX   + sumscore - CHECK_COUNT;} else if (check_count >= CHECK_COUNT && sumscore > 6) {return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;} else if (check_count >= CHECK_COUNT && maxscore > 6) {return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT;} else if (sumscore > 6) {return 2;} else {return 0;}

五、總結(jié)

從上面我們可以知道,FFmpeg檢測某個(gè)文件是否為TS文件,是通過判斷是否讀取到了同步字節(jié),以及同步字節(jié)之間的transport packet長度是否固定為188或192或204個(gè)字節(jié)實(shí)現(xiàn)的。

http://www.risenshineclean.com/news/5551.html

相關(guān)文章:

  • 做網(wǎng)站推廣什么好友情鏈接網(wǎng)站源碼
  • 做公眾號的網(wǎng)站有哪些功能如何網(wǎng)站關(guān)鍵詞優(yōu)化
  • 做畢業(yè)論文的網(wǎng)站怎樣創(chuàng)建自己的網(wǎng)站
  • 網(wǎng)站建站網(wǎng)站的seo是什么意思?
  • 建網(wǎng)站盈利的幾種方式投放廣告
  • 哪些網(wǎng)站可以接設(shè)計(jì)的單子做培訓(xùn)管理平臺
  • 新的網(wǎng)站做淘寶客搜外網(wǎng)友情鏈接
  • 如何開始做b2b網(wǎng)站站長查詢工具
  • 江西省的建設(shè)廳官方網(wǎng)站社群營銷方案
  • 可以做引流網(wǎng)站的源碼全球搜怎么樣
  • 網(wǎng)站運(yùn)營淘寶關(guān)鍵詞挖掘工具
  • 石家莊有哪些公司可以做網(wǎng)站電子商務(wù)營銷方法
  • 怎樣做音視頻宣傳網(wǎng)站正規(guī)網(wǎng)站建設(shè)公司
  • 上海商城網(wǎng)站站內(nèi)免費(fèi)推廣有哪些
  • java做網(wǎng)站的要求推廣普通話的意義50字
  • 手機(jī)開發(fā)網(wǎng)站教程如何做好一個(gè)品牌推廣
  • 尉氏做網(wǎng)站網(wǎng)絡(luò)營銷logo
  • 網(wǎng)站建設(shè)全網(wǎng)推廣網(wǎng)絡(luò)seo優(yōu)化
  • 區(qū)塊鏈開發(fā)書籍推薦搜索引擎優(yōu)化課程
  • 高新區(qū)網(wǎng)站建設(shè)的建議免費(fèi)網(wǎng)上申請注冊
  • 深圳做小程序的公司排名關(guān)鍵詞seo排名怎么做的
  • 網(wǎng)站維護(hù)與建設(shè)內(nèi)容公司網(wǎng)站設(shè)計(jì)圖
  • 高端網(wǎng)站開發(fā)找哪家好企業(yè)官方網(wǎng)站怎么申請
  • title 鎮(zhèn)江網(wǎng)站建設(shè)免費(fèi)推廣軟件
  • 鐘表珠寶商城網(wǎng)站建設(shè)百度經(jīng)驗(yàn)官網(wǎng)
  • 惠州網(wǎng)站建設(shè)學(xué)校百度學(xué)術(shù)論文官網(wǎng)入口
  • 網(wǎng)站開發(fā)文檔包括長春網(wǎng)站建設(shè)方案咨詢
  • 江蘇省建設(shè)廳網(wǎng)站施工員證查詢營銷比較好的知名公司有哪些
  • 免費(fèi)php網(wǎng)站源碼信息流推廣渠道有哪些
  • 網(wǎng)站建設(shè)中 模版模板建站哪里有