Esempio n. 1
0
        /// <exception cref="DecoderException"></exception>
        public unsafe bool TryDecode(RawAudioFrame rawAudioFrame, out int decodedFrameSize)
        {
            if (rawAudioFrame is RawAACFrame aacFrame)
            {
                Debug.Assert(aacFrame.ConfigSegment.Array != null, "aacFrame.ConfigSegment.Array != null");

                if (!_extraData.SequenceEqual(aacFrame.ConfigSegment))
                {
                    if (_extraData.Length == aacFrame.ConfigSegment.Count)
                    {
                        Buffer.BlockCopy(aacFrame.ConfigSegment.Array, aacFrame.ConfigSegment.Offset, _extraData, 0,
                                         aacFrame.ConfigSegment.Count);
                    }
                    else
                        _extraData = aacFrame.ConfigSegment.ToArray();

                    fixed(byte *extradataPtr = &_extraData[0])
                    {
                        int resultCode = FFmpegAudioPInvoke.SetAudioDecoderExtraData(_decoderHandle, (IntPtr)extradataPtr, aacFrame.ConfigSegment.Count);

                        if (resultCode != 0)
                        {
                            throw new DecoderException($"An error occurred while setting audio extra data, {_audioCodecId} codec, code: {resultCode}");
                        }
                    }
                }
            }

            Debug.Assert(rawAudioFrame.FrameSegment.Array != null, "rawAudioFrame.FrameSegment.Array != null");

            fixed(byte *rawBufferPtr = &rawAudioFrame.FrameSegment.Array[rawAudioFrame.FrameSegment.Offset])
            {
                int sampleRate;
                int bitsPerSample;
                int channels;

                int resultCode = FFmpegAudioPInvoke.DecodeFrame(_decoderHandle, (IntPtr)rawBufferPtr, rawAudioFrame.FrameSegment.Count,
                                                                out decodedFrameSize, out sampleRate, out bitsPerSample, out channels);

                _currentRawFrameTimestamp = rawAudioFrame.Timestamp;

                if (resultCode != 0)
                {
                    return(false);
                }

                if (rawAudioFrame is RawG711Frame g711Frame)
                {
                    sampleRate = g711Frame.SampleRate;
                    channels   = g711Frame.Channels;
                }

                if (_currentFrameFormat.SampleRate != sampleRate || _currentFrameFormat.BitPerSample != bitsPerSample || _currentFrameFormat.Channels != channels)
                {
                    _currentFrameFormat = new AudioFrameFormat(sampleRate, bitsPerSample, channels);
                }
            }

            return(true);
        }
        /// <exception cref="DecoderException"></exception>
        public IDecodedAudioFrame GetDecodedFrame(AudioConversionParameters optionalAudioConversionParameters = null)
        {
            IntPtr outBufferPtr;
            int    dataSize;

            AudioFrameFormat format;

            int resultCode;

            if (optionalAudioConversionParameters == null ||
                (optionalAudioConversionParameters.OutSampleRate == 0 || optionalAudioConversionParameters.OutSampleRate == _currentFrameFormat.SampleRate) &&
                (optionalAudioConversionParameters.OutBitsPerSample == 0 || optionalAudioConversionParameters.OutBitsPerSample == _currentFrameFormat.BitPerSample) &&
                (optionalAudioConversionParameters.OutChannels == 0 || optionalAudioConversionParameters.OutChannels == _currentFrameFormat.Channels))
            {
                resultCode = FFmpegAudioPInvoke.GetDecodedFrame(_decoderHandle, out outBufferPtr, out dataSize);

                if (resultCode != 0)
                {
                    throw new DecoderException($"An error occurred while getting decoded audio frame, {_audioCodecId} codec, code: {resultCode}");
                }

                format = _currentFrameFormat;
            }
            else
            {
                if (_resamplerHandle == IntPtr.Zero)
                {
                    resultCode = FFmpegAudioPInvoke.CreateAudioResampler(_decoderHandle,
                                                                         optionalAudioConversionParameters.OutSampleRate, optionalAudioConversionParameters.OutBitsPerSample,
                                                                         optionalAudioConversionParameters.OutChannels, out _resamplerHandle);

                    if (resultCode != 0)
                    {
                        throw new DecoderException($"An error occurred while creating audio resampler, code: {resultCode}");
                    }
                }

                resultCode = FFmpegAudioPInvoke.ResampleDecodedFrame(_decoderHandle, _resamplerHandle, out outBufferPtr, out dataSize);

                if (resultCode != 0)
                {
                    throw new DecoderException($"An error occurred while converting audio frame, code: {resultCode}");
                }

                format = new AudioFrameFormat(optionalAudioConversionParameters.OutSampleRate != 0 ? optionalAudioConversionParameters.OutSampleRate : _currentFrameFormat.SampleRate,
                                              optionalAudioConversionParameters.OutBitsPerSample != 0 ? optionalAudioConversionParameters.OutBitsPerSample : _currentFrameFormat.BitPerSample,
                                              optionalAudioConversionParameters.OutChannels != 0 ? optionalAudioConversionParameters.OutChannels : _currentFrameFormat.Channels);
            }

            if (_decodedFrameBuffer.Length < dataSize)
            {
                _decodedFrameBuffer = new byte[dataSize];
            }

            Marshal.Copy(outBufferPtr, _decodedFrameBuffer, 0, dataSize);
            return(new DecodedAudioFrame(_currentRawFrameTimestamp, new ArraySegment <byte>(_decodedFrameBuffer, 0, dataSize), format));
        }
Esempio n. 3
0
        /// <exception cref="DecoderException"></exception>
        public static FFmpegAudioDecoder CreateDecoder(FFmpegAudioCodecId audioCodecId, int bitsPerCodedSample)
        {
            int resultCode = FFmpegAudioPInvoke.CreateAudioDecoder(audioCodecId, bitsPerCodedSample, out IntPtr decoderPtr);

            if (resultCode != 0)
            {
                throw new DecoderException($"An error occurred while creating audio decoder for {audioCodecId} codec, code: {resultCode}");
            }

            return(new FFmpegAudioDecoder(audioCodecId, bitsPerCodedSample, decoderPtr));
        }
Esempio n. 4
0
        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }

            _disposed = true;
            FFmpegAudioPInvoke.RemoveAudioDecoder(_decoderHandle);
            GC.SuppressFinalize(this);
        }
Esempio n. 5
0
        /// <exception cref="DecoderException"></exception>
        public unsafe IDecodedAudioFrame GetDecodedFrame(ArraySegment <byte> bufferSegment)
        {
            Debug.Assert(bufferSegment.Array != null, "bufferSegment.Array != null");

            fixed(byte *outByteSegmentPtr = &bufferSegment.Array[bufferSegment.Offset])
            {
                int resultCode = FFmpegAudioPInvoke.GetDecodedFrame(_decoderHandle, (IntPtr)outByteSegmentPtr);

                if (resultCode != 0)
                {
                    throw new DecoderException($"An error occurred while getting decoded audio frame, {_audioCodecId} codec, code: {resultCode}");
                }
            }

            return(new DecodedAudioFrame(_currentRawFrameTimestamp, bufferSegment, _currentFrameFormat));
        }
        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }

            _disposed = true;
            FFmpegAudioPInvoke.RemoveAudioDecoder(_decoderHandle);

            if (_resamplerHandle != IntPtr.Zero)
            {
                FFmpegAudioPInvoke.RemoveAudioResampler(_resamplerHandle);
            }

            GC.SuppressFinalize(this);
        }
Esempio n. 7
0
        /// <exception cref="DecoderException"></exception>
        public unsafe bool TryDecode(RawAudioFrame rawAudioFrame)
        {
            if (rawAudioFrame is RawAACFrame aacFrame)
            {
                Debug.Assert(aacFrame.ConfigSegment.Array != null, "aacFrame.ConfigSegment.Array != null");

                if (!_extraData.SequenceEqual(aacFrame.ConfigSegment))
                {
                    if (_extraData.Length == aacFrame.ConfigSegment.Count)
                    {
                        Buffer.BlockCopy(aacFrame.ConfigSegment.Array, aacFrame.ConfigSegment.Offset, _extraData, 0,
                                         aacFrame.ConfigSegment.Count);
                    }
                    else
                        _extraData = aacFrame.ConfigSegment.ToArray();

                    fixed(byte *extradataPtr = &_extraData[0])
                    {
                        int resultCode = FFmpegAudioPInvoke.SetAudioDecoderExtraData(_decoderHandle, (IntPtr)extradataPtr, aacFrame.ConfigSegment.Count);

                        if (resultCode != 0)
                        {
                            throw new DecoderException($"An error occurred while setting audio extra data, {_audioCodecId} codec, code: {resultCode}");
                        }
                    }
                }
            }

            Debug.Assert(rawAudioFrame.FrameSegment.Array != null, "rawAudioFrame.FrameSegment.Array != null");

            fixed(byte *rawBufferPtr = &rawAudioFrame.FrameSegment.Array[rawAudioFrame.FrameSegment.Offset])
            {
                lock (disposalLock) {
                    if (_disposed)
                    {
                        Console.WriteLine("Skipped decoding audio frame, as decoder was disposed. (Therefore the frame probably wasn't wanted)");
                        return(false);
                    }

                    int resultCode = FFmpegAudioPInvoke.DecodeFrame(_decoderHandle, (IntPtr)rawBufferPtr,
                                                                    rawAudioFrame.FrameSegment.Count, out int sampleRate, out int bitsPerSample, out int channels);

                    _currentRawFrameTimestamp = rawAudioFrame.Timestamp;

                    if (resultCode != 0)
                    {
                        return(false);
                    }

                    if (rawAudioFrame is RawG711Frame g711Frame)
                    {
                        sampleRate = g711Frame.SampleRate;
                        channels   = g711Frame.Channels;
                    }


                    if (_currentFrameFormat.SampleRate != sampleRate || _currentFrameFormat.BitPerSample != bitsPerSample ||
                        _currentFrameFormat.Channels != channels)
                    {
                        _currentFrameFormat = new AudioFrameFormat(sampleRate, bitsPerSample, channels);

                        if (_resamplerHandle != IntPtr.Zero)
                        {
                            FFmpegAudioPInvoke.RemoveAudioResampler(_resamplerHandle);
                        }
                    }
                }
            }

            return(true);
        }