protected virtual int FindTSHeadFlag(byte[] data) { var ms = new MemoryStream(data); TSProgramManage tsms = new TSProgramManage(); int pos = 0; while (pos++ < data.Length) { // var index = ms.Position; if (ms.ReadByte() == 0x47) { int offset = (int)ms.Position - 1; if (!CheckOffsetIsPacketFlag(data, offset)) { continue; } ms.Seek(-1, SeekOrigin.Current); byte[] buf = new byte[188]; ms.Read(buf, 0, buf.Length); try { TSPacket pack = new TSPacket() { ProgramManage = tsms }; pack.SetBytes(buf); pack.Decode(); ms.Seek(-188, SeekOrigin.Current); return((int)ms.Position); } catch (Exception) { return(-1); } } } return(-1); }
public void WriteMediaTSPacket(TSPacket pack) { // Console.WriteLine(pack.PID); var data = pack.data; var newFrameFlag = data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x1 && (data[3] == 0xE0 || data[3] == 0xC0); MediaInfo mi = null; lock (_dicMediaFrameCache) { if (_dicMediaFrameCache.ContainsKey(pack.PID)) { mi = _dicMediaFrameCache[pack.PID]; } else { if (newFrameFlag) { _dicMediaFrameCache[pack.PID] = mi = new MediaInfo() { PID = pack.PID, IsVideo = pack.data[3] == 0xE0, IsAudio = pack.data[3] == 0xC0, }; } } } if (mi != null) { if (newFrameFlag) { lock (mi.TSPackets) { if ((mi.IsAudio && pack.data[3] != 0xC0) || (mi.IsVideo && pack.data[3] != 0xE0)) { lock (_dicMediaFrameCache) { foreach (var item in _dicMediaFrameCache.Values) { item.Release(); } _dicMediaFrameCache.Clear(); } return; } var mediaFrame = mi.NextMediaFrame(); if (mediaFrame != null && mediaFrame.nSize == mediaFrame.Data.Length) { OnNewMediaFrame(mediaFrame); } mi.TSPackets.Clear(); mi.TSPackets.Add(pack); } } else { lock (mi.TSPackets) mi.TSPackets.Add(pack); } } }
public static byte[] MediaFrame2TSData(MediaFrame frame, TSProgramManage pm) { var msOutput = new MemoryStream(); var pes = PESPacket.MediaFrame2PES(frame); var pes_buffer = pes.GetBytes(); var msInput = new MemoryStream(pes_buffer); int PID = frame.nIsAudio == 1 ? 257 : 258; bool isFirstPack = true; do { var payload_unit_start_indicator = 0; var size = (int)(msInput.Length - msInput.Position); var max_data_len = 188 - 4;//4B为包头长度 var data_len = 0; AdaptationInfo ai = null; if ((isFirstPack || size < max_data_len)) { if (isFirstPack && (frame.nIsAudio == 0 || true)) { max_data_len = 188 - 4 - 8; //5B为包头长度 8B为adaptation长度 data_len = Math.Min(max_data_len, size); var adaptation_field_length = 188 - 4 - data_len - 1; //1B为adaptation的头,这1B不算在adaptation_field_length中 var pcr_bas = (frame.nTimetick - pm.FirstFrameTimeTick) * 90; //这里为什么是*45我也不知道, ai = new AdaptationInfo() { adaptation_field_length = (byte)adaptation_field_length, random_access_indicator = 1, PCR_flag = 1, PCR_base = pcr_bas, }; payload_unit_start_indicator = 1; } else { max_data_len = 188 - 4 - 1;//4B为包头长度 8B为adaptation长度 if (size < max_data_len) { data_len = Math.Min(max_data_len, size); var adaptation_field_length = 188 - 4 - data_len - 1; ai = new AdaptationInfo(); ai.adaptation_field_length = (byte)adaptation_field_length; } else { payload_unit_start_indicator = 0; data_len = size; } } } else { data_len = max_data_len; } byte[] data = new byte[data_len]; msInput.Read(data, 0, data.Length); TSPacket pack_pat = new TSPacket() { sync_byte = 0x47, transport_error_indicator = 0, payload_unit_start_indicator = (byte)payload_unit_start_indicator,//一帧第一个packet或者这个packet需要fill字节时 transport_priority = 0, PID = (ushort)PID, transport_scrambling_control = 0, adaptation_field_control = (byte)(ai != null ? 3 : 1), continuity_counter = pm.GetCounter(PID), AdaptationField = ai, data = data }; var buf = pack_pat.GetBytes(); msOutput.Write(buf, 0, buf.Length); isFirstPack = false; } while (msInput.Position < msInput.Length); var result = msOutput.ToArray(); return(result); }
public static byte[] GetPMTPATData(bool isOnlyVideo = false) { if (_pmt_pat_tsdata == null) { var msOutput = new MemoryStream(); TSProgramManage ts_pm = new TSProgramManage(); TS_PAT pat = new TS_PAT(); var pat_data = pat.GetBytes(); TSPacket pack_pat = new TSPacket() { sync_byte = 0x47, transport_error_indicator = 0, payload_unit_start_indicator = 1, transport_priority = 0, PID = 0, transport_scrambling_control = 0, adaptation_field_control = 1, continuity_counter = ts_pm.GetCounter(0), data = pat_data, }; var pack_pat_data = pack_pat.GetBytes(); var pack_pat_tmp = new TSPacket() { ProgramManage = ts_pm, }; msOutput.Write(pack_pat_data, 0, pack_pat_data.Length); //pack_pat_tmp.SetBytes(pack_pat_data); //pack_pat_tmp.Decode(); TS_PMT pmt = new TS_PMT(); var pmt_data = isOnlyVideo ? pmt.GetVideoBytes() : pmt.GetBytes(); TSPacket pack_pmt = new TSPacket() { sync_byte = 0x47, transport_error_indicator = 0, payload_unit_start_indicator = 1, transport_priority = 0, PID = 256,//PMT_PID transport_scrambling_control = 0, adaptation_field_control = 1, continuity_counter = ts_pm.GetCounter(256), data = pmt_data, }; var pack_pmt_data = pack_pmt.GetBytes(); var pack_pmt_tmp = new TSPacket() { ProgramManage = ts_pm, }; msOutput.Write(pack_pmt_data, 0, pack_pmt_data.Length); //pack_pmt_tmp.SetBytes(pack_pmt_data); //pack_pmt_tmp.Decode(); var _out = msOutput.ToArray(); _pmt_pat_tsdata = _out; } return(_pmt_pat_tsdata); }
protected virtual void TSStreamResolveThread() { byte[] buffer_ts = new byte[188 * 2]; //两个包的空间,这里需要读取两个188字节的ts packet 而不是读取一个的原因是, //读取两个,当可以检验前后ts packet标识字段是否为0x47,如果不是则当前位置不是处理ts packet的开头, //则需要重新找到ts packet的头 byte[] part_ts = null;//当检测到当前ts packet错误的时候 part_ts用来保存正确的ts packet中的一部分 while (_isworking) { int readSize = 188 * 2 - (part_ts != null ? part_ts.Length : 0);//如果上一次没有残留数据则长度为 2个ts packet 的长度 if (_ioStream.Length >= readSize) { if (part_ts != null) { Array.Copy(part_ts, 0, buffer_ts, 0, part_ts.Length); //残留数据 } _ioStream.Read(buffer_ts, buffer_ts.Length - readSize, readSize); //读取到缓冲区 if (buffer_ts[0] != 0x47) { //当前为非 ts packet的头,则找到下一个ts packet的头的偏移 int offset = FindTSHeadFlag(buffer_ts); if (offset == -1)//没有找到头则返回起点 { continue; } //从2*188字节中减去偏移,再减去一个ts packet的长度得到残余的数据长度 part_ts = new byte[buffer_ts.Length - 188 - offset]; Array.Copy(buffer_ts, offset + 188, part_ts, 0, part_ts.Length); //新建一个临时的缓冲区,并将完整 的ts数据copy到这个临时缓冲区中 var tmp_buffer = new byte[188]; Array.Copy(buffer_ts, offset, tmp_buffer, 0, tmp_buffer.Length); try { TSPacket pack = new TSPacket() { ProgramManage = _tsms }; pack.SetBytes(tmp_buffer); pack.Decode(); if (pack.PacketType == TSPacketType.DATA) { pack.ProgramManage.WriteMediaTSPacket(pack); } } catch (Exception e) { _DebugEx.Trace("TSStreamInput", "解析TS失败 1" + e.ToString()); } } else { //当前为 ts packet的头,则找到下一个ts packet的头的偏移 try { //判断前后两个ts packet是否开头均正确 if (buffer_ts[0] == 0x47 && buffer_ts[188] == 0x47) { //将两个ts packet 分别解析 var tmp_buffer = new byte[188]; Array.Copy(buffer_ts, 0, tmp_buffer, 0, tmp_buffer.Length); TSPacket pack = new TSPacket() { ProgramManage = _tsms }; pack.SetBytes(tmp_buffer); pack.Decode(); if (pack.PacketType == TSPacketType.DATA) { pack.ProgramManage.WriteMediaTSPacket(pack); } Array.Copy(buffer_ts, 188, tmp_buffer, 0, tmp_buffer.Length); pack = new TSPacket() { ProgramManage = _tsms }; pack.SetBytes(tmp_buffer); pack.Decode(); if (pack.PacketType == TSPacketType.DATA) { pack.ProgramManage.WriteMediaTSPacket(pack); } } else { _DebugEx.Trace("TSStreamInput", "TS Packet HeadFlag Error"); throw new Exception("TS Packet HeadFlag Error"); } } catch (Exception e) { _DebugEx.Trace("TSStreamInput", "解析TS失败 2" + e.ToString()); } part_ts = null; } } else { Thread.Sleep(10); } } }