Example #1
0
        private void Packetize(double initialDTS)
        {
            int added = 0;

            for (int i = 0; i < Frames.Count; i++)
            {
                ByteArray pesData = PesForFrame(0, i, initialDTS);
                byte[]    pes     = pesData.buffer;

                double time = Frames[i].DTS - AdjustedVBVDelay;
                if (Frames[i].VBVDelay != 0)
                {
                    time = Frames[i].DTS - Frames[i].VBVDelay;
                }

                if (time < 0)
                {
                    time = 0;
                }

                ulong streamTime   = (ulong)(27000000.0 * time);
                ulong decoderStamp = (ulong)(27000000.0 * Frames[i].DTS);

                long frameTransmissionTime = (long)27000000 * (long)(pesData.length) / (long)(ByteRate * 100 / 100); // * 112 / 100);
                long timeIncrement         = frameTransmissionTime / ((pesData.length / 184) + 1);

                long lastPCR      = 0;
                long index        = 0;
                int  packetNumber = 0;
                while (index < pesData.length)
                {
                    TransportPacket newPacket = new TransportPacket();
                    newPacket.PID = PID;
                    newPacket.ContinuityIndicator = ContinuityIndicator;
                    ContinuityIndicator++;

                    if (index == 0)
                    {
                        newPacket.IsAligned     = true;
                        newPacket.HasAdaptation = true;
                        newPacket.HasPCR        = true;

                        if (firstPacket)
                        {
                            // MD-SP-VOD-CEP-I01040107 - Part 4.6 Transport Stream Requirements
                            // The first PCR packet of the stream must have the transport discontinuity_indicator flag set to 1.
                            newPacket.DiscontinuityIndicator = true;
                            firstPacket = false;
                        }

                        if (Frames[i].StartOfGOP)
                        {
                            // MD-SP-VOD-CEP-I01040107 - Part 4.6 Transport Stream Requirements
                            // Transport packet at the start of a GOP must have random_access_indicator set to 1.
                            newPacket.RandomAccess = true;
                        }
                    }

                    // This section forces a PCR stamp if the current frame is just so big that it will take longer than
                    // the maximum PCR interval to transmit.
                    if ((index - lastPCR) > BytesPerPCRMax)
                    {
                        newPacket.HasAdaptation = true;
                        newPacket.HasPCR        = true;
                        lastPCR = index;
                    }

                    newPacket.DecoderStamp = decoderStamp;
                    newPacket.StreamTime   = streamTime + ((ulong)timeIncrement * (ulong)packetNumber);
                    if (newPacket.StreamTime > decoderStamp)
                    {
                        throw new Exception("Buffer Overflow");
                    }

                    packetNumber++;

                    index += newPacket.Construct(pes, index, pesData.length);
                    added++;

                    TransportPackets.AddPacket(newPacket);
                }
            }

            return;
        }