Mpegts Basics Look at these blog posts:
Mpegts Foundation
Analysis of ts,pes,es structure of Mpegts
TS Stream multiplexing and multiplexing is a reverse process. TS multiplexing gets the PES bare stream of audio and video. In general, the length of each TS packet is 188 bytes, and there is also a 204-byte, which is to add 16 bytes of Rs redundancy check information after each packet. In this case, the 188 bytes are analyzed, and the rest are similar.
To iterate through the 188-byte package from the file, and then analyze the packet byte by bit, the analysis process is as follows:
The TS Package flag is the first byte beginning with 0x47
As a TS package:
Bitwise parsing, get Pid,flag, error flag, load type, PSI, PMI and other information.
Source code analysis is as follows: The source code is from an open source Tool Tsdemux interception, all of the TS Stream parsing process is nothing more than a process.
<span style= "FONT-FAMILY:SIMHEI;FONT-SIZE:18PX;" >int ts::d emuxer::d emux_ts_packet (const char* ptr) {u_int32_t timecode = 0;const char* end_ptr = ptr + 188;if (ptr[0]! = 0x47)//TS sync bytereturn-1;u_int16_t pid = To_int (ptr + 1);//get 2, 3 byteu_int8_t flags = To_byte (PTR + 3 ); bool Transport_error = pid & 0x8000;/*ts with PES package, 1: Load is pes,0: Load is not pes TS with PSI data, 1: First byte with psi section 0: First byte without psi section * /bool payload_unit_start_indicator = pid & 0x4000;bool adaptation_field_exist = flags & 0x20;bool PAYLOAD_DATA_EX IST = flags & 0x10;u_int8_t Continuity_counter = Flags & 0x0f;//get pidpid &= 0x1fff;if (transport_error) retur N-2;//empty payloadif (pid = = 0X1FFF | |!payload_data_exist) return 0;PTR + 4;//skip adaptation fieldif (Adaptation_fiel D_exist) {ptr + = To_byte (PTR) + 1;if (ptr >= end_ptr) return-3;} stream& s = streams[pid];if (!pid | | (S.channel! = 0xFFFF && S.type = = 0xff)) {//Psiif (Payload_unit_start_indicator) {//Begin of PSI tableptr++; if (ptr >= end_ptr) return-4;if (*ptr! = 0x00 && *ptr! = 0x02) return 0;if (End_ptr-ptr < 3) return-5;u_in t16_t L = to_int (ptr + 1); if (L & 0x3000! = 0x3000) return-6;l &= 0x0fff;ptr + = 3;int len = end_ptr-ptr;if (l &G T Len) {if (L > Ts::table::max_buf_len) return-7;s.psi.reset (); memcpy (S.psi.buf, PTR, Len); S.psi.offset + = Len; S.psi.len = L;return 0;} Elseend_ptr = ptr + l;} else{//Next part of Psiif (!s.psi.offset) Return-8;int len = end_ptr-ptr;if (Len > Ts::table::max_buf_len-s.psi.of Fset) return-9;memcpy (s.psi.buf + S.psi.offset, PTR, Len), S.psi.offset + = len;if (S.psi.offset < S.psi.len) return 0;el se{ptr = S.psi.buf;end_ptr = ptr + S.psi.len;}} if (!pid) {//Patptr + = 5;if (ptr >= end_ptr) return-10;int len = end_ptr-ptr-4;if (len < 0 | | len% 4) return-11 ; int n = len/4;for (int i = 0; i < n; i++, ptr + = 4) {u_int16_t channel = To_int (PTR); u_int16_t pid = To_int (ptr + 2); if (PID & 0xe000! = 0xe000) return-12;pid &= 0x1fff;iF (!demuxer::channel | | demuxer::channel = = Channel) {stream& SS = Streams[pid];ss.channel = Channel;ss.type = 0xFF;}} }else{//Pmtptr + = 7;if (ptr >= end_ptr) return-13;u_int16_t Info_len = To_int (PTR) & 0x0fff;ptr + = Info_len + 2;en D_ptr-= 4;if (ptr >= end_ptr) return-14;while (PTR < end_ptr) {if (End_ptr-ptr < 5) return-15;u_int8_t type = t O_byte (PTR); u_int16_t pid = To_int (ptr + 1); if (PID & 0xe000! = 0xe000) return-16;pid &= 0x1fff;info_len = To_int ( PTR + 3) & 0x0fff;ptr + = 5 + info_len;//Ignore unknown streamsif (Validate_type (type)) {stream& SS = Streams[pid]; if (ss.channel! = S.channel | | Ss.type! = type) {Ss.channel = S.channel;ss.type = Type;ss.id = ++s.id;if (!parse_only & &!ss.file.is_opened ()) {if (Dst.length ()) Ss.file.open (File::out, False, "%s%c%strack_%i.%s", Dst.c_str (), Os_ Slash, Prefix.c_str (), PID, Get_stream_ext (Get_stream_type (Ss.type))); Elsess.file.open (File::out, False, "%strack_% i.%s ", Prefix.c_str (), PID, GET_STREAM_EXT (Get_stream_type (Ss.type))), if (es_parse) Ss.file.open (File::out, True, "%ses_strack_%i.%s", Prefix.c_str (), PID, " Es ");}}} if (ptr! = end_ptr) return-18;}} else{if (s.type! = 0xff) {//Pesif (Payload_unit_start_indicator)//equals True represents the start of a PES package {s.psi.reset (); s.psi.len = 9;} while (s.psi.offset<s.psi.len) {int len = end_ptr-ptr;if (len <= 0) return 0;int n = s.psi.len-s.psi.offset;if (le n>n) len = n;memcpy (s.psi.buf + S.psi.offset, PTR, Len), S.psi.offset + = Len;ptr + len;if (S.psi.len = = 9) S.psi.len + = t O_byte (S.psi.buf + 8);} if (S.psi.len) {if (memcmp (S.psi.buf, "\x00\x00\x01", 3)) return-19;s.stream_id = To_byte (s.psi.buf + 3); u_int8_t flags = t O_byte (s.psi.buf + 7); S.frame_num++;switch (Flags & 0xc0) {case 0x80://PTS only Audio Packet pts and DTS are the same, so only Pts{u_int64 _t pts = decode_pts (s.psi.buf + 9), if (dump = = 2) printf ("%.4x:%llu\n", PID, pts), else if (dump = 3) printf ("%.4x:track=% .4x.%.2i, type=%.2x, stream=%.2x, pts=%llums\n ", PID, S.channel, S.id, S.type, s.stream_id, pts/ if (S.dts > 0 && pts > S.dts) s.frame_length = Pts-s.dts;s.dts = Pts;if (pts > S.last_pts) s.last_pt s = pts;if (!s.first_pts) s.first_pts = pts;} Break;case 0xc0:///Pts,dts video contains pts and dts{u_int64_t pts = decode_pts (s.psi.buf + 9); u_int64_t DTS = decode_pts (S.P Si.buf + +), if (dump = = 2) printf ("%.4x:%llu%llu\n", PID, pts, DTS), else if (dump = = 3) printf ("%.4x:track=%.4x.%.2i, Ty PE=%.2X, stream=%.2x, Pts=%llums, dts=%llums\n ", PID, S.channel, S.id, S.type, s.stream_id, pts/90, dts/90); if (S.dts > 0 && DTS > S.dts) s.frame_length = Dts-s.dts;s.dts = Dts;if (pts > s.last_pts) s.last_pts = Pts;if (!s. First_dts) S.first_dts = DTS;} break;} if (Pes_output && s.file.is_opened ()) {S.file.write (S.psi.buf, S.psi.len, false);//The PES header information is deposited into the file}s.psi.reset ( );} if (s.frame_num) {int len = end_ptr-ptr;if (s.file.is_opened ()) {S.file.write (PTR, Len, true);//This Gets the ES packet}}}}return 0;} </span>
The code is modified according to the TSDEMUX project, the source project can only be reused to get PES, on this basis to modify the simultaneous acquisition of audio and video Pes,es a total of 4 files. Students who need to learn more about TS can study it.
The source code has been uploaded to Csdn:
http://download.csdn.net/detail/rootusers/8426227
Mpegts Flow Solution Multiplexing Program (PES and ES are used for multiplexing)