1. 程式人生 > >TS流解析之一解包長

TS流解析之一解包長

參考文件ISO13181-1.pdf

解析TS流的第一個步驟就是解析出TS的包長與開始位置資訊。包的長度有188位元組和204位元組之分,而每一個packet的開頭都是0x47。

下圖是packet的結構體:


packet結構體解析,解packet長度是解析TS流的開始,不需要知道其他結構體成員的介紹。(本人只做了關鍵點的標誌):

1:sync_byte The sync_byte is a fixed 8-bit field whose value is '0100 0111' (0x47). Sync_byte emulation in the choice
of values for other regularly occurring fields, such as PID, should be avoided.

那麼當我們fopen開啟TS檔案時,如何確定當前TS的包長以及第一個有效包的位置資訊呢?由結構體資訊我們知道packet的首位元組必定是0x47,所有當我們讀取到資料是0x47時就有兩種情況,要麼這個0x47是包的同步位元組要麼不是。假如是包的同步位元組,當我們偏移包長(188或者204)之後再取值資料應該還是0x47。所有我們往後判斷十次,如果每一次偏移之後取得的值都是0x47的話說明這個位置就是第一個有效包的位置。

程式有不足之處,希望大家能夠指正出來。

int main(int argc, char *argv[])
{	
	errno_t err;
	FILE *pfTsFile = NULL;
	err = fopen_s(&pfTsFile, argv[1], "rb");
	if (err != 0)
	{
		perror("fopen .ts error!");
		return -1;
	}

	int iReturn = ParseTs(pfTsFile);

	fclose(pfTsFile);
	return iReturn;
}

int ParseTs(FILE *pfTsFile)
{
	int iTsLength = 0;
	int iTsPosition = 0;
	int iReturn = 0;

	iTsLength = ParseTsLength(pfTsFile, &iTsPosition);	
	printf("\nThe transport stream packet length is: %d\n", iTsLength);
	printf("and the first packet position is: %d\n\n", iTsPosition);

	return iReturn;
}

int ParseTsLength(FILE *pfTsFile, int *piTsPosition)
{
	char cPacketByte = 0;
	int uiPacketLength = 0;

	while ((cPacketByte = fgetc(pfTsFile)) != EOF)
	{
		if (cPacketByte == 0x47)
		{
			//printf("\nfind first ox47 in position: %d, whether the length is 188?\n",*piTsPosition);
			if (JudgmentPacketLength(pfTsFile, *piTsPosition, 188) == 188)
			{
				uiPacketLength = 188;
				goto Ret;
			}

			//printf("nfind length is no 188, whether the length is 204?\n");
			if (JudgmentPacketLength(pfTsFile, *piTsPosition, 204) == 204)
			{
				uiPacketLength = 204;
				goto Ret;
			}
		}

		//Move the cursor to the next one
		(*piTsPosition)++;
		if (fseek(pfTsFile, *piTsPosition, SEEK_SET) == -1)
		{
			perror("fseek error");
			uiPacketLength = -1;
			goto Ret;
		}
	}

	printf("This .ts file have no the transport stream.\n");
	uiPacketLength = -1;

Ret:
	return uiPacketLength;
}

static int JudgmentPacketLength(FILE *pfTsFile, int iTsPosition, int iLength)
{
	int iTime = 0;
	int iPacketByte = 0;

	if (fseek(pfTsFile, iTsPosition + 1, SEEK_SET) == -1)
	{
		printf("fseek in %d error\n", iTsPosition + 1);
		iLength = -1;
		goto Ret;
	}

	for (iTime = 0; iTime<10; iTime++)
	{
		if (fseek(pfTsFile, iLength - 1, SEEK_CUR) == -1)
		{
			printf("fseek %d error\n", iLength);
			iLength = -1;
			goto Ret;
		}
		
		if ((iPacketByte = fgetc(pfTsFile)) == EOF)
		{
			printf("after fseek %d feof\n", iLength);
			iLength = -1;
			goto Ret;
		}

		if (iPacketByte != 0x47)
		{
			//printf("Is no transport stream packet.\n");
			iLength = -1;
			goto Ret;
		}
	}

Ret:
	return iLength;
}


轉載請註明出處

相關推薦

TS解析之一

參考文件ISO13181-1.pdf 解析TS流的第一個步驟就是解析出TS的包長與開始位置資訊。包的長度有188位元組和204位元組之分,而每一個packet的開頭都是0x47。 下圖是packet的結構體: packet結構體解析,解packet長度是解析TS流的開

ts格式詳

ts檔案為傳輸流檔案,視訊編碼主要格式h264/mpeg4,音訊為acc/MP3。   ts檔案分為三層:ts層Transport Stream、pes層 Packet Elemental Stream、es層 Elementary Stream. es層就是音視訊資料,pe

hls之m3u8、ts格式詳

1、M3U8檔案    用文字方式對媒體檔案進行描述,由一系列標籤組成。 #EXTM3U #EXT-X-TARGETDURATION:5 #EXTINF:5, ./0.ts #EXTINF:5, ./1.ts #EXTM3U:每個M3U8檔案第一行必須是這個tag。 #EXT-X-TARGETDURATIO

socket位元組解析(網路抓解析)

研究了一下PHP和C++socket通訊,用C++作為伺服器端,php作為客戶端進行. socket通訊是基於協議的,因此,只要雙方協議一致就行. 關於協議的選擇:我看過網上大部分協議都是在應用層的協議,選用這樣的協議很方便,基本上就是字串傳過來,傳過去 本次研究的協議算是當今國際化的一個標準做法.leng

dubbo-php-framework的資料和組邏輯解析

前面分析了框架的請求和回覆實體的封裝,而在進行底層網路通訊時,需要進行解包(收到資料)和組包(傳送資料),框架底層使用了dubbo協議,資料序列化方式是json格式,這篇文章我們就重點看看解包和組包的邏輯,這部分邏輯在DubboParser類中完成,這個類定義在dubbo-p

【Android音視訊】TS資料解析和Jni2Java回撥

為了解析傳輸到手機的TS流有效視訊資料,進行預覽播放和錄製等功能,在網上看到的部分關於android播放TS流,如UDP預覽播放,採取的方式真是夠標新立異,如通過儲存到本地ts檔案然後播放,會有閃屏現象等,當然也有很多的播放器支援播放,如ffmepg-and

Halcon中二維碼解析函式位元速率和時的優化方法

       在解碼入門之後,下面介紹的就是本文的重頭戲。在工業級別的解碼器上,首先要考慮的需求有兩個,一是解位元速率儘可能高,二是CT時間儘可能短,也就是解碼所耗費的時間儘可能短。因此,如果簡單使用最大化解碼的引數,在無法解碼的情況下就會導致解碼耗時過長,而不使用最大化解碼引數,則解位元速率會有所下降。那

利用ML&AI判定未知惡意程式——裡面提到ssl惡意加密檢測使用N個payload CNN + 位元組分佈等特徵綜合判定

利用ML&AI判定未知惡意程式 導語:0x01、前言 在上一篇ML&AI如何在雲態勢感知產品中落地中介紹了,為什麼我們要預測未知惡意程式,傳統的安全產品已經無法滿足現有的安全態勢。那麼我們要使用新的技術手段武裝我們的安全產品,通過大資料的手段更好的解決未知惡意程式

ffmpeg對ts解析

下面我們來分析,在ISO/IEC 13818-1裡有說明,PAT(Program Association Table)的PID值為0x00,TS包的標識(即sync_byte)為0x47,並且為了確保這個TS包裡的資料有效,所以我們一開始查詢47 40 00這三組16進位制數,為什麼這樣?具體的奧祕在TS包

修改ffmpeg原始碼,並用它對多路節目TS複用及播放

原始碼地址會在這裡告訴大家https://edu.csdn.net/course/play/8542 目前,很多所謂的萬能播放器都沒有新增對多路視訊流視訊的支援。 DVB數字電視經常是多路複用的視訊流,如下圖用vlc播放一個多路視訊的視訊時,播放器首先要解析到所有節目資訊

PES,TS,PS,RTP等的打包格式解析TS

上一篇描述了PES包頭的封裝格式,本篇描述一下TS包的封包格式 1.TS包頭格式 TS流,即傳輸流,是對PES包的進一步封裝,基本單位為TS包,固定每包大小為188位元組(或204位元組,在18

ts解析工作總結

近段時間,由於工作需要,初步研究學習了TS流的解析,多少有些心得體會,這裡與大家分享一下(大牛可以無視,呵呵)。 已編碼的音視訊資料,按照PES格式進行第一次打包,即PES包。一系列PES包,也有一種叫法叫PES分組。 PES包有幾個比較重要的欄位(摘自13818標準文件): 分組起始碼字首欄位  p

法詳之一(LK光

ref 像素點 需要 and intel nal get 灰度值 參考文獻 Lucas–Kanade光流算法是一種兩幀差分的光流估計算法。它由Bruce D. Lucas 和 Takeo Kanade提出 [1]。 LK光流法有三個假設條件: 1. 亮度恒定

java Io 類詳

修改 文件目錄 != exe [] 深入 clas one fileinput 關於java 流類的復習;習慣性的復習按照圖結構一層層往下深入去了解去復習,最後通過代碼來實現感覺印象會更深刻一些; 關於 I/O流:IO可以理解為JAVA用來傳遞數據的管道

TS之代碼分析

xtra new 校正 reat ted 跟著 ror enable 好的   代碼分析前,先要了解TS流基本概念:TS流之基本概念。   VLC解析TS流是通過libts庫來分離的,libts庫使用libdvbpsi庫來解TS表。 1. libts庫在加載的時候,會將以下

mpeg2 tsPAT,PMT,SDT的定義

pack audio scrip pro 末尾 .com 最大數 length pes 轉自: http://blog.sina.com.cn/s/blog_5ea0192f0100vo15.html 更具體準確的信息請參考iso13818-1,都在裏面定義的 PAT的定義

xpack文件打包代碼庫

strong tom androi and -c 進行 lan 索引 文件目錄結構 Github ###概述 xpack是一個文件資源打包工具及類庫,可以對多文件進行打包解包。 其使用文件名的hash作為索引,建立hash索引表以加速文件查找。 ###特性 支持has

JavaScript 經典之一

如果 空字符串 domo 然而 logs bsp 學習 相同 com 作為一個前端開發者,閉包是必須要攻克掉的障礙。據說好多面試者掛在閉包面試上。下面我就給大家講一下我理解中的閉包。不說太多的廢話,直接進入主題。 變量作用域 學習編程語言需要明白,變量的作用域。變量作用域分

一個簡單的SOCKET程序的數據結構和封函數

... 服務 windows print class 學生 define bsp include /*練習寫套接字通信程序時候寫的一段代碼,本來想寫個聊天室但寫來寫去進度卡在界面上接節下來都是通信部分的代碼 因為只是試驗用所以都是用C寫的,等界面部分完工後會用類來封裝一下

Java之集合初探(二)Iterator(叠代器),collections,打包/(裝箱拆箱),泛型(Generic),comparable接口

基本 generate 等於 框架 ring bin list() each 是否 Iterator(叠代器) 所有實現了Collection接口的容器都有一個iterator方法, 用來返回一個實現了Iterator接口的對象 Iterator對象稱作叠代器, 用來