Пример #1
0
 public byte[] CreateFlvFrame(List <H264NALU> nALUs, int minimumLength = 10240)
 {
     byte[] buffer = FlvArrayPool.Rent(minimumLength);
     try
     {
         FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer);
         int      currentMarkPosition = 0;
         int      nextMarkPosition = 0;
         H264NALU?sps = null, pps = null;
         foreach (var naln in nALUs)
         {
             string key = naln.GetKey();
             if (!FrameInitDict.ContainsKey(key))
             {
                 if (naln.NALUHeader.NalUnitType == 7)
                 {
                     naln.RawData = H264Decoder.DiscardEmulationPreventionBytes(naln.RawData);
                     sps          = naln;
                 }
                 else if (naln.NALUHeader.NalUnitType == 8)
                 {
                     pps = naln;
                 }
                 if (sps != null && pps != null)
                 {
                     flvMessagePackWriter.WriteArray(CreateFlvFirstFrame(sps, pps));
                     FrameInitDict.TryAdd(key, true);
                 }
                 else
                 {
                     continue;
                 }
             }
             if (PreviousTagSizeDict.TryGetValue(key, out uint previousTagSize))
             {
                 currentMarkPosition = flvMessagePackWriter.GetCurrentPosition();
                 CreateVideoTagOtherFrame(ref flvMessagePackWriter, previousTagSize, naln);
                 nextMarkPosition = flvMessagePackWriter.GetCurrentPosition();
                 uint tmpPreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength);
                 PreviousTagSizeDict.TryUpdate(key, tmpPreviousTagSize, previousTagSize);
             }
         }
         return(flvMessagePackWriter.FlushAndGetArray());
     }
     finally
     {
         FlvArrayPool.Return(buffer);
     }
 }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sps">NalUnitType->7</param>
        /// <param name="pps">NalUnitType->8</param>
        /// <returns></returns>
        public byte[] CreateFlvFirstFrame(H264NALU sps, H264NALU pps)
        {
            byte[] buffer = FlvArrayPool.Rent(65535);
            int    currentMarkPosition = 0;
            int    nextMarkPosition    = 0;

            try
            {
                FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer);
                //flv header
                flvMessagePackWriter.WriteArray(VideoFlvHeaderBuffer);

                //SPS -> 7
                ExpGolombReader h264GolombReader = new ExpGolombReader(sps.RawData);
                var             spsInfo          = h264GolombReader.ReadSPS();

                currentMarkPosition = flvMessagePackWriter.GetCurrentPosition();
                //flv body script tag
                CreateScriptTagFrame(ref flvMessagePackWriter, spsInfo.width, spsInfo.height);
                nextMarkPosition = flvMessagePackWriter.GetCurrentPosition();

                //flv body video tag
                uint scriptTagFramePreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength);
                AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord = new AVCDecoderConfigurationRecord();
                aVCDecoderConfigurationRecord.AVCProfileIndication      = spsInfo.profileIdc;
                aVCDecoderConfigurationRecord.ProfileCompatibility      = (byte)spsInfo.profileCompat;
                aVCDecoderConfigurationRecord.AVCLevelIndication        = spsInfo.levelIdc;
                aVCDecoderConfigurationRecord.NumOfPictureParameterSets = 1;
                aVCDecoderConfigurationRecord.PPSBuffer = pps.RawData;
                aVCDecoderConfigurationRecord.SPSBuffer = sps.RawData;

                currentMarkPosition = flvMessagePackWriter.GetCurrentPosition();
                CreateVideoTag0Frame(ref flvMessagePackWriter, scriptTagFramePreviousTagSize, aVCDecoderConfigurationRecord);
                nextMarkPosition = flvMessagePackWriter.GetCurrentPosition();

                //flv body video tag 0
                uint videoTag0PreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength);
                //cache PreviousTagSize
                PreviousTagSizeDict.AddOrUpdate(sps.GetKey(), videoTag0PreviousTagSize, (a, b) => videoTag0PreviousTagSize);

                return(flvMessagePackWriter.FlushAndGetArray());
            }
            finally
            {
                FlvArrayPool.Return(buffer);
            }
        }