/// <summary> /// Wird zur eigentlichen Steuerung der Entschlüsselung aufgerufen. /// </summary> /// <param name="pmt">Die Informationen zur Quelle.</param> /// <param name="reset">Gesetzt, um einen Neustart der Entschlüsselung zu erzwingen.</param> private void Decrypt( EPG.Tables.PMT pmt, bool reset ) { // Check the interface var setPtr = ComIdentity.QueryInterface( m_DataGraph.TunerFilter.Interface, typeof( KsPropertySetFireDTV.Interface ) ); if (setPtr == IntPtr.Zero) return; // Process using (var propertySet = new KsPropertySetFireDTV( setPtr )) try { // Load property identifier var propSetId = PropertySetId; var supported = propertySet.QuerySupported( ref propSetId, BDAProperties.SendCA ); if ((PropertySetSupportedTypes.Set & supported) != PropertySetSupportedTypes.Set) return; // Process reset if (reset) propertySet.Send( CACommand.CreateReset() ); else if (pmt == null) propertySet.Send( CACommand.StopDecryption() ); else propertySet.Send( CACommand.CreateDecrypt( pmt ) ); } catch { // Forward if not resetting if (pmt != null) throw; } }
/// <summary> /// Adds a new page container with its required fields to an existing document container /// </summary> /// <param name="docContainer">The container of the existing document in the AFP to add the page to</param> /// <param name="pageName">The optional 8 character name of the new page</param> /// <param name="groupName">The optional 8 character name of the new active environment group</param> /// <param name="xUnitsPer10Inches">The number of horizontal measurement units on a page/presentation space for every 10 inches</param> /// <param name="yUnitsPer10Inches">The number of vertical units on a page/presentation space for every 10 inches</param> /// <param name="pageUnitWidth">The number of units that represent the page's width. To convert to inches: (pageUnitWidth / xUnitsPer10Inches) * 10</param> /// <param name="pageUnitHeight">The number of units that represent the page's height. To convert to inches: (pageUnitHeight / yUnitsPer10Inches) * 10</param> /// <returns>The resulting page's container</returns> public Container AddPageToDocument(Container docContainer, string pageName = "", string groupName = "", ushort xUnitsPer10Inches = 3000, ushort yUnitsPer10Inches = 3000, ushort pageUnitWidth = 2550, ushort pageUnitHeight = 3300) { Container pageContainer = null; // Verify the container parameter is truly a document if (!(docContainer.Structures[0] is BDT && docContainer.Structures.Last() is EDT)) { throw new Exception("The passed container parameter does not appear to be a Document container."); } // Verify the document exists in the container (and store index to insert if it's ok) int indexToInsert = 0; for (int i = 0; i < Fields.Count; i++) { // As soon as we find the begin tag, verify each field in the container matches and break if (Fields[i] == docContainer.Structures[0]) { for (int j = 0; j < docContainer.Structures.Count; j++) { if (Fields[i + j] != docContainer.Structures[j]) { throw new Exception("Invalid container - does not exist in list of fields."); } } indexToInsert = (i + docContainer.Structures.Count) - 1; break; } } // Create page tags BPG newBPG = new BPG(pageName); EPG newEPG = new EPG(pageName); // A page needs an active environment group BAG newBAG = new BAG(groupName); EAG newAEG = new EAG(groupName); // An active environment group in a page needs both page and presentation text descriptor fields PGD newPGD = new PGD(xUnitsPer10Inches, yUnitsPer10Inches, pageUnitWidth, pageUnitHeight); PTD1 newPTD = new PTD1(xUnitsPer10Inches, yUnitsPer10Inches, pageUnitWidth, pageUnitHeight); // Build the list of new fields and add them to the end of the document List <StructuredField> newFields = new List <StructuredField>() { newBPG, newBAG, newPGD, newPTD, newAEG, newEPG }; AddFields(newFields, indexToInsert); // Set and return the created page's container pageContainer = newBPG.LowestLevelContainer; return(pageContainer); }
/// <summary> /// Wird zur eigentlichen Steuerung der Entschlüsselung aufgerufen. /// </summary> /// <param name="pmt">Die Informationen zur Quelle.</param> private void Decrypt( EPG.Tables.PMT pmt ) { // Connect once Open( m_DataGraph.TunerFilter ); // Just wait a bit if (m_TuneDelay > 0) Thread.Sleep( m_TuneDelay ); // Create full section and process var table = pmt.Section.CreateSITable().Skip( 1 ).ToArray(); var error = bdaapiCIReadPSIFastWithPMT( Device, table, (ushort) table.Length ); if (error != APIErrorCodes.Success) throw new DVBException( error.ToString() ); }
/// <summary> /// Wertet eine PMT aus. /// </summary> /// <param name="pmt">Die angeforderte PMT.</param> private void ProcessPMT( EPG.Tables.PMT pmt ) { // Skip if (pmt == null) return; if (!pmt.IsValid) return; // Load receiver var sink = Interlocked.Exchange( ref m_PMTSink, null ); if (sink != null) try { // Process sink( pmt ); } catch (Exception e) { // Maybe log does not yet exist try { // Report and ignore EventLog.WriteEntry( "DVB.NET", e.ToString(), EventLogEntryType.Error ); } catch { // At least trace it Trace.WriteLine( e.ToString() ); } } }
/// <summary> /// Create a new transport stream identifier for a new stream /// in this transport stream. /// </summary> /// <param name="type">Type of the stream.</param> /// <param name="encoding">Encoding type of the stream.</param> /// <param name="isPCR">Set if the stream will be the PCR reference.</param> /// <param name="noPTS">Set if the stream should not participate in PTS synchronisation.</param> /// <param name="info">Information on the contents of a subtitle stream.</param> /// <param name="noPCR">Set to disable PCR from PTS generation.</param> /// <returns>A randomly choosen but unique transport stream identifier.</returns> private short AddStream( StreamTypes type, byte encoding, bool noPCR, bool noPTS, EPG.SubtitleInfo[] info, out bool isPCR ) { // Create pid short pid = NextPID++; // Make key int keyPID = pid; // Forward isPCR = ProgramMap.Add( type, encoding, pid, noPCR, info ); // Reload lock (m_Queue) { // Force PAT change PATSent = false; // Load Packet buffers = (Packet) m_Buffers[keyPID]; // Create new if (null == buffers) { // Create new buffers = new Packet( this, keyPID ); // Remember m_Buffers[keyPID] = buffers; } // Set up if (StreamTypes.Video == type) buffers.SetAudioVideo( true ); else if ((StreamTypes.Audio == type) || (StreamTypes.Private == type)) buffers.SetAudioVideo( false ); // May disable PTS synchronisation (e.g. for TeleText streams) buffers.IgnorePTS = noPTS; } // Report return pid; }
/// <summary> /// Create a new stream holding DVB subtitles. /// </summary> /// <param name="info">Information on the contents of this subtitle stream.</param> /// <returns>The new subtitle stream.</returns> public SubtitleStream AddSubtitles( EPG.SubtitleInfo[] info ) { // Flag bool isPCR; // Run short pid = AddStream( StreamTypes.SubTitles, 255, false, true, info, out isPCR ); // Create SubtitleStream sub = new SubtitleStream( this, pid, isPCR ); // Remember m_Streams.Add( sub ); // Make it the guide if ((null != m_Splitter) && (0 == m_GuidePID)) m_GuidePID = pid; // Report return sub; }
/// <summary> /// Ergänzt einen Eintrag der Programmzeitschrift. /// </summary> /// <param name="eit">Ein beliebiger Eintrag der Programmzeitschrift.</param> public void AddEventTable( EPG.Tables.EIT eit ) { // Ignore until PCR is available if (m_PCRAvailable <= 0) return; // Load the current mapping var mapping = EPGMapping; // Not enabled if (null == mapping) return; // None if ((null == eit) || !eit.IsValid) return; // Compare - by service first because normally the rest is equal if (mapping.Service != eit.ServiceIdentifier) return; if (mapping.Network != eit.OriginalNetworkIdentifier) return; if (mapping.TransportStream != eit.TransportStreamIdentifier) return; // Update the table eit.OriginalNetworkIdentifier = (ushort) ProgramAssociation.NetworkIdentifier; eit.TransportStreamIdentifier = 1; eit.ServiceIdentifier = (ushort) ProgramAssociation.ProgramNumber; // Has running or nearly running? if (!Array.Exists( eit.Entries, entry => (EPG.EventStatus.Running == entry.Status) || (EPG.EventStatus.NotRunning == entry.Status) )) return; // Try to recreate byte[] table = eit.Section.CreateSITable(); // Inject if (null != table) SendTable( ref m_EPGCounter, 0x12, table ); }
/// <summary> /// Ergänzt einen Eintrag der Programmzeitschrift. /// </summary> /// <param name="section">Ein beliebiger Eintrag der Programmzeitschrift.</param> public void AddEventTable( EPG.Section section ) { // Forward if (null != section) if (section.IsValid) AddEventTable( section.Table as EPG.Tables.EIT ); }
/// <summary> /// Prüft, ob die EPG Informationen zum aktuellen Sender und der laufenden Sendung /// gehören und vermerkt diese dann. /// </summary> /// <param name="section">Die EPG Informationen.</param> /// <param name="current">Kennung des aktuellen Senders.</param> protected void ProcessEPG( EPG.Section section, SourceIdentifier current ) { // Test station if (current == null) return; // Test section if (section == null) return; if (!section.IsValid) return; // Test table var eit = section.Table as EPG.Tables.EIT; if (eit == null) return; if (!eit.IsValid) return; // Test identification if (current.Service != eit.ServiceIdentifier) return; if (current.Network != eit.OriginalNetworkIdentifier) return; if (current.TransportStream != eit.TransportStreamIdentifier) return; // Check mode bool gotCurrent = false, gotNext = false; // Test state foreach (var entry in eit.Entries) { // Check for current entry if (!gotCurrent) if (entry.Status == EPG.EventStatus.Running) { // Remember CurrentEntry = entry; gotCurrent = true; // Done if (gotNext) break; // Next continue; } // Check for next entry if (!gotNext) if (entry.Status == EPG.EventStatus.NotRunning) { // Remember NextEntry = entry; gotNext = true; // Done if (gotCurrent) break; } } }