MPEG PS封裝格式

2022-06-25 19:12:09 字數 3854 閱讀 8516

據傳輸**的質量不同,mpeg-2中定義了兩種復合資訊流:傳送流(ts:transportstream)和節目流(ps:programstream)

s流與ps流的區別在於ts流的包結構是固定長度的,而ps流的包結構是可變長度的。

ps包與ts包在結構上的這種差異,導致了它們對傳輸誤碼具有不同的抵抗能力,因而應用的環境也有所不同。ts碼流由於採用了固定長度的包結構,當傳輸誤碼破壞了某一ts包的同步資訊時,接收機可在固定的位置檢測它後麵包中的同步資訊,從而恢復同步,避免了資訊丟失。而ps包由於長度是變化的,一旦某一ps包的同步資訊丟失,接收機無法確定下一包的同步位置,就會造成失步,導致嚴重的資訊丟失。因此,在通道環境較為惡劣,傳輸誤碼較高時,一般採用ts碼流;而在通道環境較好,傳輸誤碼較低時,一般採用ps碼流。由於ts碼流具有較強的抵抗傳輸誤碼的能力,因此目前在傳輸**中進行傳輸的mpeg-2碼流基本上都採用了ts碼流的包格式。

乙個完整的mpeg-2檔案就是乙個ps流檔案。使用elecard streamanalyzer開啟乙個mpeg-2檔案,得到下面資訊。

下面就分別來分析ps檔案的 ps和pes包。

ps層主要由pack header和資料組成,pack header中各個bit的意義如下

我們可以通過分析乙個示例檔案來了解它

其中system_clock_reference的意義如下

scr and scr_ext together are the system clock reference, a counter driven at 27mhz, used as a reference to synchronize streams. the clock is divided by 300 (to match the 90khz clocks such as pts/dts), the quotient is scr (33 bits), the remainder is scr_ext (9 bits)

參考自:

system_clock_reference_base的計算方法為:

scr += packet_size * 90000ll / (mux_rate * 50ll);
基本資訊了解完了,下面就開始定義這個結構了,一開始是採用了位域來定義的

struct

pack_header

void getsystem_clock_reference_base(uint64 &_ui64scr)

void

setsystem_clock_reference_base(uint64 _ui64scr)

void getprogram_mux_rate(unsigned int &_uimux_rate)

void setprogram_mux_rate(unsigned int

_uimux_rate)

};

這樣的好處是可以直接通過

pack_header header;

header.setprogram_mux_rate(

25200

);header.setsystem_clock_reference_base(0);

os.write((

char *)&header, sizeof(header));

來寫入檔案,但是不方便抽象成類,所以就參考ffmpeg使用了put_bits的方式

class packheader : public

headerbase

;

然後在類中加乙個序列化函式,來將整個類序列化

int

packheader::serialize()

}if ((calcbinarybitlen / 8) >binarylen)

binarylen = calcbinarybitlen / 8

; byte* p =binary;

bits_buffer_t bw;

bits_initwrite(&bw, binarylen, p);

bits_write(&bw, 32, pack_header_start_code); //

pack_start_code

bits_write(&bw, 2, 0x1); //

'01'

bits_write(&bw, 3, (scrbase >> 30) & 0x07); //

system_clock_reference_base [32..30]

bits_write(&bw, 1, 1); //

marker_bit

bits_write(&bw, 15, (scrbase >> 15) & 0x7fff); //

system_clock_reference_base [29..15]

bits_write(&bw, 1, 1); //

marker_bit

bits_write(&bw, 15, scrbase & 0x7fff); //

system_clock_reference_base [14..0]

bits_write(&bw, 1, 1); //

marker_bit

bits_write(&bw, 9, scrext); //

system_clock_reference_extension

bits_write(&bw, 1, 1); //

marker_bit

bits_write(&bw, 22, programmuxrate & 0x3fffff); //

program_mux_rate

bits_write(&bw, 1, 1); //

marker_bit

bits_write(&bw, 1, 1); //

marker_bit

bits_write(&bw, 5, 0x1f); //

reserved

bits_write(&bw, 3, stuffinglength & 0x07); //

pack_stuffing_length

if (stuffinglength > 0

)

}return1;

}

對於***而言,一般開始的pack裡面還有乙個system header

我們也可以通過分析乙個示例檔案來了解它

封裝格式 FLV 檔案格式解析

flv檔案主要由兩部分組成 header和body。header部分記錄了flv的型別 版本等資訊,是flv的開頭,一般都差不多,佔9bytes。具體格式如下 檔案型別 3 bytes flv 版本1 byte 一般為0x01 流資訊1 byte header長度 4 bytes 整個header的...

CURL方法封裝 與JSON格式返回封裝

封裝curl的呼叫介面,post的請求方式 param url param requeststring param int timeout return bool mixed function docurlpostrequest url,requeststring,timeout 5,json 1 ...

moment 時間格式的封裝

在這使用乙個時間工具類來做乙個格式規劃,獲取時間的格式你可以自己定義。在這主要是用來 獲取前一天的時間,時間分隔點為1小時,獲取前一周的時間,時間間隔為一天,獲取前乙個的時間,時間間隔為一天 eslint disable import moment from moment import moment...