Ejemplo n.º 1
0
        public int Decode(EncodedBuffer input, ArraySegment <float> output)
        {
            //Packet lost, clear the output buffer
            if (!input.Encoded.HasValue || input.PacketLost)
            {
                // ReSharper disable once AssignNullToNotNullAttribute (Justification: Array segment cannot be null)
                Array.Clear(output.Array, output.Offset, output.Count);
                return(output.Count);
            }

            var inputArray = input.Encoded.Value.Array;

            if (inputArray == null)
            {
                throw new ArgumentNullException("input");
            }

            var outputArray = output.Array;

            if (outputArray == null)
            {
                throw new ArgumentNullException("output");
            }

            var bytes = input.Encoded.Value.Count;

            if (bytes > output.Count * sizeof(float))
            {
                throw new ArgumentException("output buffer is too small");
            }

            Buffer.BlockCopy(inputArray, input.Encoded.Value.Offset, outputArray, output.Offset, bytes);
            return(input.Encoded.Value.Count / sizeof(float));
        }
Ejemplo n.º 2
0
        eNaluAction iVideoTrackReader.writeNextNalu(EncodedBuffer dest)
        {
            Debug.Assert(dest.state == eBufferState.User);
            if (sampleReader.EOF)
            {
                return(eNaluAction.EOF);
            }

            eNaluAction result;

            if (state.currentOffset >= state.sampleSize)
            {
                // First NALU in the sample
                state.sampleSize    = sampleReader.seek(stream);
                state.currentOffset = writeNalu(dest, out result, out var type);
                // Logger.logVerbose( "Wrote a first NALU of a sample into buffer #{0}; sample size {1}, NALU size {2}, type {3}", dest.index, state.sampleSize, state.currentOffset, type );
            }
            else
            {
                // Some other NALU from the same sample
                sampleReader.seekToNalu(stream, state.currentOffset);
                int cb = writeNalu(dest, out result, out var type);
                state.currentOffset += cb;
                // Logger.logVerbose( "Wrote a NALU of a sample into buffer #{0}; NALU size {1}, type {2}", dest.index, cb, type );
            }

            if (state.currentOffset >= state.sampleSize)
            {
                // No more NALUs left in the sample, advance sample reader to the next one. This may set EOF flag, when the music is over.
                sampleReader.advance();
                state.sampleSize = 0;
            }
            return(result);
        }
Ejemplo n.º 3
0
        eNaluAction setBufferMetadata(EncodedBuffer destBuffer, ReadOnlySpan <byte> data)
        {
            eNaluType naluType = (eNaluType)(data[0] & 0x1f);
            BitReader reader   = new BitReader(data);

            reader.skipBits(8);

            switch (naluType)
            {
            case eNaluType.IDR:
            case eNaluType.NonIDR:
            {
                uint first_mb_in_slice = reader.unsignedGolomb();                                   // address of the first macroblock in the slice
                uint slice_type        = reader.unsignedGolomb();
                if (slice_type > 9)
                {
                    throw new ArgumentException("Malformed h264 stream, slice_type must be in [ 0 .. 9 ] interval");
                }
                destBuffer.setSliceTypeFlag(slice_type);
            }
                destBuffer.setTimestamp(timestamp);
                return(eNaluAction.Decode);

            case eNaluType.SEI:
                // Logger.logVerbose( "Ignoring SEI NALU" );
                return(eNaluAction.Ignore);

            default:
                // Logger.logVerbose( "{0} NALU", naluType );
                // destBuffer.setTimestamp( sampleReader.timestamp );
                return(eNaluAction.Decode);
            }
        }
        public int Decode(EncodedBuffer input, ArraySegment <float> output)
        {
            //Clear output buffer so that it just contains silence
            output.Clear();

            //Output the length of a frame
            return(_frameSize);
        }
Ejemplo n.º 5
0
        SecsAsyncResult SendDataMessage(SecsMessage msg, int systembyte, AsyncCallback callback = null, object syncState = null)
        {
            if (State != ConnectionState.Selected)
            {
                throw new SecsException("Device is not selected");
            }

            var header = new Header(new byte[10])
            {
                S             = msg.S,
                F             = msg.F,
                ReplyExpected = msg.ReplyExpected,
                DeviceId      = DeviceId,
                SystemBytes   = systembyte
            };
            var buffer = new EncodedBuffer(header.Bytes, msg.RawDatas);

            SecsAsyncResult ar = null;

            if (msg.ReplyExpected)
            {
                ar = new SecsAsyncResult(msg, callback, syncState);
                _replyExpectedMsgs[systembyte] = ar;

                ThreadPool.RegisterWaitForSingleObject(ar.AsyncWaitHandle,
                                                       (state, timeout) =>
                {
                    SecsAsyncResult ars;
                    if (_replyExpectedMsgs.TryRemove((int)state, out ars) && timeout)
                    {
                        _tracer.TraceError($"T3 Timeout[id=0x{state:X8}]");
                        ars.EndProcess(null, timeout);
                    }
                }, systembyte, T3, true);
            }

            SocketError error;

            _socket.Send(buffer, SocketFlags.None, out error);
            if (error != SocketError.Success)
            {
                var errorMsg = "Socket send error :" + new SocketException((int)error).Message;
                _tracer.TraceError(errorMsg);
                CommunicationStateChanging(ConnectionState.Retry);
                throw new SecsException(errorMsg);
            }

            _tracer.TraceMessageOut(msg, systembyte);
            return(ar);
        }
Ejemplo n.º 6
0
        internal override void writeParameters(EncodedBuffer buffer, eParameterSet which)
        {
            switch (which)
            {
            case eParameterSet.SPS:
                buffer.writeSps(sps[0]);
                return;

            case eParameterSet.PPS:
                buffer.writePps(pps[0]);
                return;

            case eParameterSet.VPS:
                throw new NotImplementedException("VPS is only for h.265 video which is not yet implemented");

            default:
                throw new ArgumentException($"Unexpected eParameterSet set value { which }");
            }
        }
Ejemplo n.º 7
0
        /* protected override int writeFrame( EncodedBuffer destBuffer, int cb )
         * {
         *      // Read the complete sample
         *      Span<byte> dest = destBuffer.span;
         *      stream.Read( dest.Slice( 0, cb ) );
         *
         *      // Produce NALU start codes.
         *      for( int offset = 0; offset < cb; )
         *      {
         *              int naluLength = ( dest[ offset ] << 16 ) | ( dest[ offset + 1 ] << 8 ) | dest[ offset + 2 ];
         *
         *              dest[ offset ] = 0;
         *              dest[ offset + 1 ] = 0;
         *              dest[ offset + 2 ] = 1;
         *
         *              offset += ( naluLength + 3 );
         *      }
         *      return cb;
         * } */

        protected override int writeNalu(EncodedBuffer destBuffer, out eNaluAction result, out eNaluType type)
        {
            Span <byte> naluLength = stackalloc byte[4];

            naluLength[0] = 0;
            stream.read(naluLength.Slice(1));
            int cbNalu = BitConverter.ToInt32(naluLength).endian();

            Span <byte> dest = destBuffer.span;

            // Write NALU start code to mapped memory
            EmulationPrevention.writeStartCode4(dest, 0);
            // Read NALU payload from file into mapped memory
            Span <byte> naluPayload = dest.Slice(4, cbNalu);

            stream.read(naluPayload);
            destBuffer.setLength(cbNalu + 4);
            type = setBufferMetadata(destBuffer, naluPayload, out result);
            return(cbNalu + 3);
        }
Ejemplo n.º 8
0
        eNaluAction iVideoTrackReader.writeNextNalu(EncodedBuffer dest)
        {
            if (EOF)
            {
                return(eNaluAction.EOF);
            }

            int         naluLength;
            Span <byte> naluPayload;

            lock (clusters.syncRoot)
            {
                // Seek to the blob
                seek(ref readerState);

                // Read 4-bytes NALU length. Unlike mpeg4, MKV header never says it's 4 bytes, i.e. just guessing here.
                Span <byte> naluLengthSpan = stackalloc byte[4];
                read(ref readerState, naluLengthSpan);
                naluLength = BinaryPrimitives.ReadInt32BigEndian(naluLengthSpan);
                Debug.Assert(readerState.bytesLeft >= naluLength);

                // Write NALU start code to mapped memory
                EmulationPrevention.writeStartCode4(dest.span, 0);

                // Write the payload
                naluPayload = dest.span.Slice(4, naluLength);
                read(ref readerState, naluPayload);
            }

            dest.setLength(naluLength + 4);

            // Parse the payload. The shared memory mapped by the driver is both readable and writeable.
            eNaluAction act = setBufferMetadata(dest, naluPayload);

            if (readerState.bytesLeft <= 0)
            {
                advance();
            }
            return(act);
        }
Ejemplo n.º 9
0
        public bool Read(ArraySegment <float> frame)
        {
            VoicePacket?encoded;
            bool        peekLostPacket;
            var         lastFrame = _buffer.Read(out encoded, out peekLostPacket);

            var p = new EncodedBuffer(encoded.HasValue ? encoded.Value.EncodedAudioFrame : (ArraySegment <byte>?)null, peekLostPacket || !encoded.HasValue);

            //Decode the frame
            int decodedCount = _decoder.Decode(p, frame);

            //If it was not a lost frame, also decode the metadata
            if (!p.PacketLost && encoded.HasValue)
            {
                //Expose the playback options for this packet
                using (var l = _options.Lock())
                    l.Value = encoded.Value.PlaybackOptions;

                //Read the channel data into a separate list
                ExtractChannels(encoded.Value);

                //Recycle the frame for re-use with a future packet. Only done with frames which were not peek ahead frames
                _recycleFrame(encoded.Value);
            }

            //Sanity check that decoding got correct number of samples
            if (decodedCount != _frameSize)
            {
                throw new InvalidOperationException(string.Format("Decoding a frame of audio got {0} samples, but should have decoded {1} samples", decodedCount, _frameSize));
            }

            if (_diagnosticOutput != null)
            {
                _diagnosticOutput.WriteSamples(frame);
            }

            return(lastFrame);
        }
Ejemplo n.º 10
0
 public int Decode(EncodedBuffer input, ArraySegment <float> output)
 {
     return(_decoder.DecodeFloats(input, output));
 }
Ejemplo n.º 11
0
            /// <summary>
            /// Decodes audio samples.
            /// </summary>
            /// <param name="srcEncodedBuffer">Encoded data (or null, to reconstruct a missing frame)</param>
            /// <param name="dstBuffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values starting at offset replaced with audio samples.</param>
            /// <returns>The number of floats decoded and written to dstBuffer.</returns>
            /// <remarks>Set srcEncodedBuffer to null to instruct the decoder that a packet was dropped.</remarks>
            public int DecodeFloats(EncodedBuffer srcEncodedBuffer, ArraySegment <float> dstBuffer)
            {
                int length;

                using (var decoder = _decoder.Lock())
                {
                    if (decoder.Value == IntPtr.Zero)
                    {
                        throw new DissonanceException(Log.PossibleBugMessage("Attempted to access a null Opus decoder", "16261551-968B-44A8-80A1-E8DFB0109469"));
                    }

                    //Decode some data into the dstBuffer
                    // - We have the packet => run decode
                    // - We have a packet but lost flag is set => run FEC (if allowed)
                    // - We have no packet => Run PLC
                    using (var dstHandle = dstBuffer.Pin())
                    {
                        if (!srcEncodedBuffer.Encoded.HasValue || (srcEncodedBuffer.PacketLost && !EnableForwardErrorCorrection))
                        {
                            Log.Trace("Lost packet, but not applying FEC (srcEncodedBuffer.Encoded.HasValue:{0}, EnableForwardErrorCorrection:{1}", srcEncodedBuffer.Encoded.HasValue, EnableForwardErrorCorrection);

                            // We've lost a packet but cannot apply FEC because either we don't know what the next packet is (required for FEC) or FEC is explicitly disabled.
                            // Call decoder with null pointer and zero length to invoke basic packet loss concealment
                            length = OpusNativeMethods.opus_decode_float(
                                decoder.Value,
                                IntPtr.Zero,
                                0,
                                dstHandle.Ptr,
                                dstBuffer.Count,
                                false
                                );
                        }
                        else
                        {
                            // Either we have a packet, or FEC is enabled and we have the _next_ packet
                            using (var srcHandle = srcEncodedBuffer.Encoded.Value.Pin())
                            {
                                length = OpusNativeMethods.opus_decode_float(
                                    decoder.Value,
                                    srcHandle.Ptr,
                                    srcEncodedBuffer.Encoded.Value.Count,
                                    dstHandle.Ptr,
                                    dstBuffer.Count,
                                    srcEncodedBuffer.PacketLost
                                    );
                            }
                        }
                    }
                }

                if (length < 0)
                {
                    if (length == (int)OpusErrors.InvalidPacket)
                    {
                        if (!srcEncodedBuffer.Encoded.HasValue)
                        {
                            throw new OpusException(Log.PossibleBugMessage("Decoding failed: InvalidPacket. 'null' ", "03BE7561-3BCC-4F41-A7CB-C80F03981267"));
                        }
                        else
                        {
                            var arr = srcEncodedBuffer.Encoded.Value;
                            // ReSharper disable once AssignNullToNotNullAttribute (Justification Array of the segment isn't null here)
                            throw new OpusException(Log.PossibleBugMessage(string.Format("Decoding failed: InvalidPacket. '{0}'", Convert.ToBase64String(arr.Array, arr.Offset, arr.Count)), "EF4BC24C-491E-45D9-974C-FE5CB61BD54E"));
                        }
                    }
                    else
                    {
                        throw new OpusException(Log.PossibleBugMessage(string.Format("Decoding failed: {0} ", (OpusErrors)length), "A9C8EF2C-7830-4D8E-9D6E-EF0B9827E0A8"));
                    }
                }
                return(length);
            }
Ejemplo n.º 12
0
 internal abstract void writeParameters(EncodedBuffer buffer, eParameterSet which);
Ejemplo n.º 13
0
        protected eNaluType setBufferMetadata(EncodedBuffer destBuffer, ReadOnlySpan <byte> data, out eNaluAction result)
        {
            // NALU header
            eNaluType naluType = (eNaluType)(data[0] & 0x1f);
            BitReader reader   = new BitReader(data);

            reader.skipBits(8);

            switch (naluType)
            {
            case eNaluType.IDR:
            case eNaluType.NonIDR:
            {
                uint first_mb_in_slice = reader.unsignedGolomb();                                   // address of the first macroblock in the slice
                uint slice_type        = reader.unsignedGolomb();
                if (slice_type > 9)
                {
                    throw new ArgumentException("Malformed h264 stream, slice_type must be in [ 0 .. 9 ] interval");
                }
                destBuffer.setSliceTypeFlag(slice_type);

                uint pic_parameter_set_id = reader.unsignedGolomb();
                if (separateColourPlaneFlag)
                {
                    reader.skipBits(2);                                         // uint colour_plane_id
                }
                int frameIndex = reader.readInt(frameIndexBits);
                // Logger.logVerbose( "{0} NALU: slice type {1}, frame index {2}", naluType, (eSliceType)slice_type, frameIndex );
                // if( naluType != eNaluType.NonIDR )
                //	Logger.logVerbose( "{0} NALU: slice type {1}, frame index {2}", naluType, (eSliceType)slice_type, frameIndex );
            }
                destBuffer.setTimestamp(sampleReader.timestamp);
                result = eNaluAction.Decode;
                return(naluType);

            case eNaluType.SEI:
            {
                sSeiMessage sei = new sSeiMessage(ref reader, ref timingFormat);
                if (sei.type == eSeiType.PicTiming)
                {
                    // ISO/IEC 14496-15 section 5.2.2:
                    // All timing information is external to stream.
                    // Timing provided within the AVC stream in this file format should be ignored as it may contradict the timing provided by the file format and may not be correct or consistent within itself.
                    result = eNaluAction.Ignore;
                }
                else
                {
                    // Logger.logVerbose( "{0} NALU: {1}", naluType, sei );
                    // destBuffer.setTimestamp( sampleReader.timestamp );
                    result = eNaluAction.Decode;
                }
                return(naluType);
            }

            default:
                // Logger.logVerbose( "{0} NALU", naluType );
                // destBuffer.setTimestamp( sampleReader.timestamp );
                result = eNaluAction.Decode;
                return(naluType);
            }
        }
Ejemplo n.º 14
0
        /// <summary>Write complete sample to the buffer.</summary>
        /// <remarks>This requires <see cref="Linux.eImageFormatDescriptionFlags.ContinuousByteStream" /> capability flag for the h264 format.
        /// Needless to say, Pi4 hardware decoder ain’t supporting that flag.</remarks>
        // protected abstract int writeFrame( EncodedBuffer dest, int cb );

        /// <summary>Write a single NALU to the buffer, including start code. Returns count of bytes read from the file.</summary>
        protected abstract int writeNalu(EncodedBuffer dest, out eNaluAction result, out eNaluType type);