private MediaFrame AnalyzeNewFrame(PESPacket pes, bool isAudio) { MediaFrame result = null;; if (!isAudio) { var esdata = pes.PES_Packet_Data; if (_listVideoPES.Count > 0 && esdata[0] == 0 && esdata[1] == 0 && esdata[2] == 0 && esdata[3] == 1) { var stream = new MemoryStream(); foreach (var item in _listVideoPES) { stream.Write(item.PES_Packet_Data, 0, item.PES_Packet_Data.Length); } long tick = _listVideoPES.FirstOrDefault().GetVideoTimetick(); esdata = stream.ToArray(); var frame = CreateVideoMediaFrame(esdata, tick); if (frame != null) { result = frame; _queueFrame.Enqueue(frame); } _listVideoPES.Clear(); } _listVideoPES.Add(pes); } else { //不处理音频 //var esdata = pes.PES_Packet_Data; //if (_listAudioPES.Count > 0 && esdata[0] == 0xFF && (esdata[1] & 0xF0) == 0xF0) { // var stream = new MemoryStream(); // foreach (var item in _listAudioPES) { // stream.Write(item.PES_Packet_Data, 0, item.PES_Packet_Data.Length); // } // long tick = _listAudioPES.FirstOrDefault().GetAudioTimetick(); // esdata = stream.ToArray(); // var frame = CreateAudioMediaFrame(esdata, tick); // _queueFrame.Enqueue(frame); // _listAudioPES.Clear(); //} //_listAudioPES.Add(pes); } return(result); }
private void AnalyzeThead() { long scr = 0; while (_isWorking) { bool findStartCode = false; byte flag = 0; lock (_lock) { if (ms.Length - ms.ReadPosition > 4) { findStartCode = ms.ReadByte() == 0x00 && ms.ReadByte() == 0x00 && ms.ReadByte() == 0x01; if (findStartCode) { flag = (byte)ms.ReadByte(); if (flag == 0xBA || flag == 0xBB || flag == 0xBC || flag == 0xE0 || flag == 0xC0) { ms.Seek(-4, SeekOrigin.Current); } } } } if (findStartCode) { try { switch (flag) { case 0xBA: //PS流包头 var ph = new PSPacketHeader(ms); scr = ph.GetSCR(); break; case 0xBB: //PS流系统头,有些流没有该值 new PSSystemHeader(ms); break; case 0xBC: //PS流map var map = new PSMap(ms); break; case 0xE0: //PES包(视频) var pesVideo = new PESPacket(); pesVideo.SetBytes(ms); var frame = AnalyzeNewFrame(pesVideo, false); if (frame != null) { frame.NTimetick = scr; } if (frame != null && frame.IsKeyFrame == 1) { lock (_lock) ms = ms.Tolave(); } break; case 0xC0: //PES包(音频) var pesAudio = new PESPacket(); pesAudio.SetBytes(ms); AnalyzeNewFrame(pesAudio, true); break; case 0xBD: byte[] lenbuf = new byte[2]; ms.Read(lenbuf, 0, 2); var len = BitConverter.ToInt16(lenbuf, 0); len = IPAddress.HostToNetworkOrder((short)len); lenbuf = new byte[len]; ms.Read(lenbuf, 0, len); break; } } catch (Exception) { //if (_isWorking && SS.Base.AppConfig._D) //{ // //GLib.DebugEx.WriteLog(e); // throw; //} } } } }
public MediaFrame NextMediaFrame() { var success = CheckTSPack(); if (!success) { return(null); } if (TSPackets.Count == 0) { return(null); } //验证PES包头 if (TSPackets[0].data[0] != 0 || TSPackets[0].data[1] != 0 || TSPackets[0].data[2] != 1) { TSPackets = new List <TSPacket>(); return(null); } var tmp_tspackets = TSPackets; TSPackets = new List <TSPacket>(); var stream = new MemoryStream(); foreach (var item in tmp_tspackets) { stream.Write(item.data, 0, item.data.Length); } stream.Position = 0; var pes = new PESPacket(); pes.SetBytes(stream); if (IsVideo) { var esdata = pes.PES_Packet_Data; //新的一帧 if (PESPackets.Count > 0 && esdata[0] == 0 && esdata[1] == 0 && esdata[2] == 0 && esdata[3] == 1) { stream = new MemoryStream(); foreach (var item in PESPackets) { stream.Write(item.PES_Packet_Data, 0, item.PES_Packet_Data.Length); } long tick = PESPackets.FirstOrDefault().GetVideoTimetick(); esdata = stream.ToArray(); var frame = CreateVideoMediaFrame(esdata, tick);; PESPackets = new List <PESPacket>(); PESPackets.Add(pes); return(frame); } else { PESPackets.Add(pes); return(null); } } else if (IsAudio) { var esdata = pes.PES_Packet_Data; //新的一帧 if (PESPackets.Count > 0 && esdata[0] == 0xFF && (esdata[1] & 0xF0) == 0xF0) { stream = new MemoryStream(); foreach (var item in PESPackets) { stream.Write(item.PES_Packet_Data, 0, item.PES_Packet_Data.Length); } long tick = PESPackets.FirstOrDefault().GetAudioTimetick(); PESPackets = new List <PESPacket>(); PESPackets.Add(pes); esdata = stream.ToArray(); return(CreateAudioMediaFrame(esdata, tick)); } else { PESPackets.Add(pes); return(null); } } return(null); }
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.IsAudio == 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.IsAudio == 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 { 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); }