解码H.264 NALU流C#

时间:2017-09-11 08:48:22

标签: c# video-streaming h.264 decoder

1- Live Bosch IP camera Stream

2-流格式是H.264 AVC

3-如“ISO / IEC 14496-15高级视频编码(AVC)文件格式”中所述,NALU被打包在流项中,即,单个NALU以网络字节顺序由4字节长度字段分隔。

 private unsafe byte[] PostProcessPayload(Guid codingType, byte[] dataBuffer)
    {
        if ((codingType == VsdkGuids.CodingType_H264) && m_convertH264StreamItems)
        {
            //
            // "This stream item consists of one or multiple H.264 Network Abstraction Layer Units 
            // (NALUs) ITU-T Rec. H.264 / ISO/IEC 14496-10 Advanced Video Coding belonging to the same timestamp.

            // It is guaranteed that each item including an IDR picture will also include the corresponding picture 
            // parameter set and sequence parameter set NALUs. 

            //The NALUs are packed in the stream item as described in 
            // "ISO/IEC 14496-15 Advanced Video Coding (AVC) file format", i.e. single NALUs are separated 
            // by a 4 byte length field in network byte order. 
            // Since the frame boundary is implicitly communicated (each stream item represents a frame), 
            // frames usually do not carry an explicit access unit delimiter at the end. 
            // In case interlaced video is received, two fields are packet into a single stream item."
            //

            // The following code section replaces the 4 byte NALU lengths with NALU separators and appends an access delimiter at frame end.

            // The data buffer that contains the H.264 frame must be allocated with enough headroom (6 bytes after the last NALU) 
            // for the access delimiter. When such a processed payload data is written into a file of type *.h264, the VLC player for example is able 
            // to play that file (in this Complete C# Sample, connect a device proxy, set the property ConvertH264StreamItems of 
            // a video datastream to "true", add the device proxy to the end nodes, start this video stream, and stop it after a while. Then simply 
            // rename the written DataStream_{unique identifier}_Video.dat file to *.h264 and play this file with VLC).
            int remainingLength = dataBuffer.Length - H264_ACCESS_DELIMITER.Length;
            fixed (byte* pDataBuffer = &dataBuffer[0], pDelimiterBuffer = &H264_ACCESS_DELIMITER[0], pSeparatorBuffer = &H264_NALU_SEPARATOR[0])
            {
                byte* pData = pDataBuffer;
                while (remainingLength > H264_NALU_SEPARATOR.Length)
                {
                    int naluLength = System.Net.IPAddress.NetworkToHostOrder(*(Int32*)pData);

                    // replace NALU length with NALU separator
                    for (int i = 0; i < H264_NALU_SEPARATOR.Length; i++)
                        pData[i] = pSeparatorBuffer[i];

                    // goto next NALU
                    int offsetToNextNalu = H264_NALU_SEPARATOR.Length + naluLength;
                    pData += offsetToNextNalu;
                    remainingLength -= offsetToNextNalu;
                }

                if (remainingLength != 0)
                    Common.Log("Warning: Inconsistency in postprocessing of H.264 stream item, remaining length {0} is not zero", remainingLength);

                // append access delimiter after last NALU, there will be no access violation here because the buffer had been allocated with enough headroom
                for (int i = 0; i < H264_ACCESS_DELIMITER.Length; i++)
                    pData[i] = pDelimiterBuffer[i];
            }
        }
        return dataBuffer;
    }

如何从C#中的dataBuffer获取帧图像?

0 个答案:

没有答案