public WorkerFileDataSearch(StreamParserContext owner, MessageHandlerDelegate messageCallbackFromOwner, SearchRequest searchRequest) : base(owner, messageCallbackFromOwner) { this.sectionManager = new ManagerSection(owner); this.streamDemux = new StreamDemux(owner); this.searchRequest = searchRequest; //In search mode. We will not parse standard SI/PSI sections, instead ,we will set up a filter for the expected data. Filter filterForSearch = null; if (searchRequest.SearchType == DataType.SECTION) { //To search sections. filterForSearch = new Filter(owner, HandleDataFromDemux, searchRequest.SearchType, searchRequest.SelectedPid, searchRequest.FilterMask.Length, searchRequest.FilterMask, searchRequest.FilterMatch); } else { //To search TS packet or PES packet. filterForSearch = new Filter(owner, HandleDataFromDemux, searchRequest.SearchType, searchRequest.SelectedPid); } //In order to fitler out what we are expecting. streamDemux.AddFilter(filterForSearch); }
//Process some special sections that we expect. private void ProcessSection(DataStore section) { byte[] data = section.GetData(); Result result = new Result(); //Clean up offset and cutoff!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! section.Reset(); if (data[0] == (byte)TableId.PAT) { List <Service> serviceList = new List <Service>(); result = serviceManager.ProcessPatSection(section, serviceList); if (serviceList.Count > 0) { foreach (Service service in serviceList) { //Check service ID, in case PID for NIT is different from what we expect. if (0 == service.ServiceId) { if ((UInt16)TsPID.NIT != (service.PmtPid)) { //Set up filter to filter out NIT if NIT's PID in PAT is different from what we expect. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, service.PmtPid, //PID. 1, //Filter depth. new byte[1] { 0xFE }, //Mask.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!0xFE!!!!!!!!!!!!!!!!! new byte[1] { (byte)TableId.NIT_ACTUAL })); //Match. //Set the type.!!!!!!!!!!!!!!!!! pidManager.SetPidTypePlus(service.PmtPid, DataType.SECTION, "NIT"); } } else { //Set up filter to filter out PMT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, service.PmtPid, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.PMT })); //Match. //Set the type.!!!!!!!!!!!!!!!!! pidManager.SetPidTypePlus(service.PmtPid, DataType.SECTION, "PMT PID for service: " + Utility.GetValueHexString(service.ServiceId, 16)); } } } }//PAT else if (data[0] == (byte)TableId.PMT) { Service service = null; result = serviceManager.ProcessPmtSection(section, out service); if (result.Fine) { pidManager.SetPidTypePlus(service.PcrPid, DataType.TS_PACKET, "PCR PID for service: " + Utility.GetValueHexString(service.ServiceId, 16)); List <CaDescriptor> caDescriptorList = service.GetCaDescriptorList(); foreach (CaDescriptor caDescriptor in caDescriptorList) { pidManager.SetPidTypePlus(caDescriptor.CaPid, DataType.SECTION, "ECM PID for service: " + Utility.GetValueHexString(service.ServiceId, 16) + " CA_system_ID: " + Utility.GetValueHexString(caDescriptor.CaSystemId, 16)); } List <ComponentStream> componentStreamList = service.GetComponentStreamList(); foreach (ComponentStream componentStream in componentStreamList) { pidManager.SetPidTypePlus(componentStream.ElementaryPid, DataType.PES_PACKET, "Component stream for service: " + Utility.GetValueHexString(service.ServiceId, 16) + " Type: " + DataParser.GetStreamTypeName(componentStream.StreamType)); //To update according to component level CA descriptor. foreach (CaDescriptor caDescriptor in componentStream.GetCaDescriptorList()) { pidManager.SetPidTypePlus(caDescriptor.CaPid, DataType.SECTION, "ECM PID for service: " + Utility.GetValueHexString(service.ServiceId, 16) + " CA_system_ID: " + Utility.GetValueHexString(caDescriptor.CaSystemId, 16)); } } } }//PMT else if (data[0] == (byte)TableId.CAT) { List <CaDescriptor> caDescriptorList = new List <CaDescriptor>(); result = serviceManager.ProcessCatSection(section, caDescriptorList); if (result.Fine) { foreach (CaDescriptor caDescriptor in caDescriptorList) { pidManager.SetPidTypePlus(caDescriptor.CaPid, DataType.SECTION, "EMM PID for CA_system_ID: " + Utility.GetValueHexString(caDescriptor.CaSystemId, 16)); } } } //CAT } //ProcessSection
//Enable standard filters to receive SI/PSI sections. public void EnableStandardFilters(StreamDemux streamDemux) { //To filter PAT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.PAT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.PAT })); //Match. //To filter CAT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.CAT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.CAT })); //Match. //To filter TSDT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.TSDT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.TSDT })); //Match. //To filter NIT for current network and for other network. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.NIT, //PID. 1, //Filter depth. new byte[1] { 0xFE }, //Mask. To filter out table ID 0x40 and 0x41. new byte[1] { (byte)TableId.NIT_ACTUAL })); //Match. //To filter SDT for current stream and for other stream. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.BAT_SDT, //PID. 1, //Filter depth. new byte[1] { 0xFB }, //Mask.To filter out table ID 0x42 and 0x46. new byte[1] { (byte)TableId.SDT_ACTUAL })); //Match. //To filter BAT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.BAT_SDT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.BAT })); //Match. //To filter EIT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.EIT, //PID. 1, //Filter depth. new byte[1] { 0xFE }, //Mask. To filter out table ID 0x4E and 0x4F. new byte[1] { (byte)TableId.EIT_PF_ACTUAL })); //Match. //To filter EIT schedule for current stream. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.EIT, //PID. 1, //Filter depth. new byte[1] { 0xF0 }, //Mask. To filter out table ID 0x50 to 0x5F. new byte[1] { (byte)TableId.EIT_SCHEDULE_ACTUAL })); //Match. //To filter EIT schedule for other stream. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.EIT, //PID. 1, //Filter depth. new byte[1] { 0xF0 }, //Mask. To filter out table ID 0x50 to 0x5F. new byte[1] { (byte)TableId.EIT_SCHEDULE_OTHER })); //Match. //To filter RST. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.RST, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.RST })); //Match. //To filter TDT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.TDT_TOT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.TDT })); //Match. //To filter TOT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.TDT_TOT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.TOT })); //Match. //To filter DIT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.DIT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.DIT })); //Match. //To filter SIT. streamDemux.AddFilter(new Filter(GetContext(), ProcessFilteredData, DataType.SECTION, (UInt16)TsPID.SIT, //PID. 1, //Filter depth. new byte[1] { 0xFF }, //Mask. new byte[1] { (byte)TableId.SIT })); //Match. }