private SoundFormat SoundFormatCallback(SoundFormat sf) { if (!_needsSetup) { return(sf); } _needsSetup = false; int chan = _realChannels = sf.Channels; if (chan > 1) { chan = 2;//downmix } _recordingFormat = new WaveFormat(sf.Rate, 16, chan); _waveProvider = new BufferedWaveProvider(RecordingFormat); _sampleChannel = new SampleChannel(_waveProvider); _sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; if (HasAudioStream == null) { return(sf); } HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; return(sf); }
private void ProcessAudio(IntPtr data, IntPtr samples, uint count, long pts) { if (!IsRunning || _ignoreAudio || _quit) { return; } _lastFrame = DateTime.UtcNow; _connecting = false; var da = DataAvailable; int bytes = (int)count * 2;//(16 bit, 1 channel) if (HasAudioStream != null) { HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; } if (da != null) { var buf = new byte[bytes]; Marshal.Copy(samples, buf, 0, bytes); if (!_audioInited) { _audioInited = true; _waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(200) }; _sampleChannel = new SampleChannel(_waveProvider); _sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; } _waveProvider.AddSamples(buf, 0, bytes); var sampleBuffer = new float[bytes]; var read = _sampleChannel.Read(sampleBuffer, 0, bytes); da(this, new DataAvailableEventArgs(buf, bytes)); if (Listening) { WaveOutProvider?.AddSamples(buf, 0, bytes); } } }
void ProcessAudio(byte[] data) { if (HasAudioStream != null) { HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; } try { if (DataAvailable != null) { _audioQueue.Enqueue(data); } } catch (NullReferenceException) { //DataAvailable can be removed at any time } catch (Exception ex) { Logger.LogExceptionToFile(ex, "FFMPEG"); } }
private void ReadFrames() { AVFrame * pConvertedFrame = null; sbyte * pConvertedFrameBuffer = null; SwsContext *pConvertContext = null; BufferedWaveProvider waveProvider = null; SampleChannel sampleChannel = null; bool audioInited = false; bool videoInited = false; var packet = new AVPacket(); do { ffmpeg.av_init_packet(&packet); AVFrame *frame = ffmpeg.av_frame_alloc(); ffmpeg.av_frame_unref(frame); if (ffmpeg.av_read_frame(_formatContext, &packet) < 0) { _stopReadingFrames = true; _res = ReasonToFinishPlaying.VideoSourceError; break; } if ((packet.flags & ffmpeg.AV_PKT_FLAG_CORRUPT) == ffmpeg.AV_PKT_FLAG_CORRUPT) { break; } AVPacket packetTemp = packet; var nf = NewFrame; var da = DataAvailable; _lastPacket = DateTime.UtcNow; if (_audioStream != null && packetTemp.stream_index == _audioStream->index) { if (HasAudioStream != null) { HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; } if (da != null) { int s = 0; var buffer = new sbyte[_audioCodecContext->sample_rate * 2]; var tbuffer = new sbyte[_audioCodecContext->sample_rate * 2]; bool b = false; fixed(sbyte **outPtrs = new sbyte *[32]) { fixed(sbyte *bPtr = &tbuffer[0]) { outPtrs[0] = bPtr; do { int gotFrame = 0; int inUsed = ffmpeg.avcodec_decode_audio4(_audioCodecContext, frame, &gotFrame, &packetTemp); if (inUsed < 0 || gotFrame == 0) { b = true; break; } int numSamplesOut = ffmpeg.swr_convert(_swrContext, outPtrs, _audioCodecContext->sample_rate, &frame->data0, frame->nb_samples); var l = numSamplesOut * 2 * _audioCodecContext->channels; Buffer.BlockCopy(tbuffer, 0, buffer, s, l); s += l; packetTemp.data += inUsed; packetTemp.size -= inUsed; } while (packetTemp.size > 0); } } if (b) { break; } ffmpeg.av_free_packet(&packet); ffmpeg.av_frame_free(&frame); if (!audioInited) { audioInited = true; RecordingFormat = new WaveFormat(_audioCodecContext->sample_rate, 16, _audioCodecContext->channels); waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(500) }; sampleChannel = new SampleChannel(waveProvider); sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; } byte[] ba = new byte[s]; Buffer.BlockCopy(buffer, 0, ba, 0, s); waveProvider.AddSamples(ba, 0, s); var sampleBuffer = new float[s]; int read = sampleChannel.Read(sampleBuffer, 0, s); da(this, new DataAvailableEventArgs(ba, read)); if (Listening) { WaveOutProvider?.AddSamples(ba, 0, read); } } } if (nf != null && _videoStream != null && packet.stream_index == _videoStream->index) { int frameFinished = 0; //decode video frame int ret = ffmpeg.avcodec_decode_video2(_codecContext, frame, &frameFinished, &packetTemp); if (ret < 0) { ffmpeg.av_free_packet(&packet); ffmpeg.av_frame_free(&frame); break; } if (frameFinished == 1) { if (!videoInited) { videoInited = true; pConvertedFrame = ffmpeg.av_frame_alloc(); var convertedFrameBufferSize = ffmpeg.avpicture_get_size(AVPixelFormat.AV_PIX_FMT_BGR24, _codecContext->width, _codecContext->height); pConvertedFrameBuffer = (sbyte *)ffmpeg.av_malloc((ulong)convertedFrameBufferSize); ffmpeg.avpicture_fill((AVPicture *)pConvertedFrame, pConvertedFrameBuffer, AVPixelFormat.AV_PIX_FMT_BGR24, _codecContext->width, _codecContext->height); pConvertContext = ffmpeg.sws_getContext(_codecContext->width, _codecContext->height, _codecContext->pix_fmt, _codecContext->width, _codecContext->height, AVPixelFormat.AV_PIX_FMT_BGR24, ffmpeg.SWS_FAST_BILINEAR, null, null, null); } var src = &frame->data0; var dst = &pConvertedFrame->data0; var srcStride = frame->linesize; var dstStride = pConvertedFrame->linesize; ffmpeg.sws_scale(pConvertContext, src, srcStride, 0, _codecContext->height, dst, dstStride); var convertedFrameAddress = pConvertedFrame->data0; if (convertedFrameAddress != null) { var imageBufferPtr = new IntPtr(convertedFrameAddress); var linesize = dstStride[0]; if (frame->decode_error_flags > 0) { ffmpeg.av_free_packet(&packet); ffmpeg.av_frame_free(&frame); break; } using ( var mat = new Bitmap(_codecContext->width, _codecContext->height, linesize, PixelFormat.Format24bppRgb, imageBufferPtr)) { var nfe = new NewFrameEventArgs((Bitmap)mat.Clone()); nf.Invoke(this, nfe); } _lastVideoFrame = DateTime.UtcNow; } } } if (_videoStream != null) { if ((DateTime.UtcNow - _lastVideoFrame).TotalMilliseconds > _timeout) { _res = ReasonToFinishPlaying.DeviceLost; _stopReadingFrames = true; } } ffmpeg.av_free_packet(&packet); ffmpeg.av_frame_free(&frame); } while (!_stopReadingFrames && !MainForm.ShuttingDown); try { Program.FfmpegMutex.WaitOne(); if (pConvertedFrame != null) { ffmpeg.av_free(pConvertedFrame); } if (pConvertedFrameBuffer != null) { ffmpeg.av_free(pConvertedFrameBuffer); } if (_formatContext != null) { if (_formatContext->streams != null) { int j = (int)_formatContext->nb_streams; for (var i = j - 1; i >= 0; i--) { AVStream *stream = _formatContext->streams[i]; if (stream != null && stream->codec != null && stream->codec->codec != null) { stream->discard = AVDiscard.AVDISCARD_ALL; ffmpeg.avcodec_close(stream->codec); } } } fixed(AVFormatContext **f = &_formatContext) { ffmpeg.avformat_close_input(f); } _formatContext = null; } _videoStream = null; _audioStream = null; _audioCodecContext = null; _codecContext = null; if (_swrContext != null) { fixed(SwrContext **s = &_swrContext) { ffmpeg.swr_free(s); } _swrContext = null; } if (pConvertContext != null) { ffmpeg.sws_freeContext(pConvertContext); } if (sampleChannel != null) { sampleChannel.PreVolumeMeter -= SampleChannelPreVolumeMeter; sampleChannel = null; } } catch (Exception ex) { Logger.LogException(ex, "Media Stream (close)"); } finally { try { Program.FfmpegMutex.ReleaseMutex(); } catch { } } PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res)); AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res)); }
private void ReadFrames() { pConvertedFrameBuffer = IntPtr.Zero; pConvertContext = null; var audioInited = false; var videoInited = false; byte[] buffer = null, tbuffer = null; var dstData = new byte_ptrArray4(); var dstLinesize = new int_array4(); BufferedWaveProvider waveProvider = null; sampleChannel = null; var packet = new AVPacket(); do { ffmpeg.av_init_packet(&packet); if (_audioCodecContext != null && buffer == null) { buffer = new byte[_audioCodecContext->sample_rate * 2]; tbuffer = new byte[_audioCodecContext->sample_rate * 2]; } if (Log("AV_READ_FRAME", ffmpeg.av_read_frame(_formatContext, &packet))) { break; } if ((packet.flags & ffmpeg.AV_PKT_FLAG_CORRUPT) == ffmpeg.AV_PKT_FLAG_CORRUPT) { break; } var nf = NewFrame; var da = DataAvailable; _lastPacket = DateTime.UtcNow; var ret = -11; //EAGAIN if (_audioStream != null && packet.stream_index == _audioStream->index && _audioCodecContext != null && !_ignoreAudio) { if (HasAudioStream != null) { HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; } if (da != null) { var s = 0; fixed(byte **outPtrs = new byte *[32]) { fixed(byte *bPtr = &tbuffer[0]) { outPtrs[0] = bPtr; var af = ffmpeg.av_frame_alloc(); ffmpeg.avcodec_send_packet(_audioCodecContext, &packet); do { ret = ffmpeg.avcodec_receive_frame(_audioCodecContext, af); if (ret == 0) { int numSamplesOut = 0; try { if (_swrContext == null) { //need to do this here as send_packet can change channel layout and throw an exception below initSWR(); } var dat = af->data[0]; numSamplesOut = ffmpeg.swr_convert(_swrContext, outPtrs, _audioCodecContext->sample_rate, &dat, af->nb_samples); } catch (Exception ex) { Logger.LogException(ex, "MediaStream - Audio Read"); _ignoreAudio = true; break; } if (numSamplesOut > 0) { var l = numSamplesOut * 2 * OutFormat.Channels; Buffer.BlockCopy(tbuffer, 0, buffer, s, l); s += l; } else { ret = numSamplesOut; //(error) } } if (af->decode_error_flags > 0) { break; } } while (ret == 0); ffmpeg.av_frame_free(&af); if (s > 0) { var ba = new byte[s]; Buffer.BlockCopy(buffer, 0, ba, 0, s); if (!audioInited) { audioInited = true; RecordingFormat = new WaveFormat(_audioCodecContext->sample_rate, 16, _audioCodecContext->channels); waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(200) }; sampleChannel = new SampleChannel(waveProvider); sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; } waveProvider.AddSamples(ba, 0, s); var sampleBuffer = new float[s]; var read = sampleChannel.Read(sampleBuffer, 0, s); da(this, new DataAvailableEventArgs(ba, s)); if (Listening) { WaveOutProvider?.AddSamples(ba, 0, read); } } } } } } if (nf != null && _videoStream != null && packet.stream_index == _videoStream->index && _videoCodecContext != null) { var ef = ShouldEmitFrame; ffmpeg.avcodec_send_packet(_videoCodecContext, &packet); do { var vf = ffmpeg.av_frame_alloc(); ret = ffmpeg.avcodec_receive_frame(_videoCodecContext, vf); if (ret == 0 && ef) { AVPixelFormat srcFmt; if (_hwDeviceCtx != null) { srcFmt = AVPixelFormat.AV_PIX_FMT_NV12; var output = ffmpeg.av_frame_alloc(); ffmpeg.av_hwframe_transfer_data(output, vf, 0); ffmpeg.av_frame_copy_props(output, vf); ffmpeg.av_frame_free(&vf); vf = output; } else { srcFmt = (AVPixelFormat)vf->format; } if (!videoInited) { videoInited = true; _finalSize = Helper.CalcResizeSize(_source.settings.resize, new Size(_videoCodecContext->width, _videoCodecContext->height), new Size(_source.settings.resizeWidth, _source.settings.resizeHeight)); var convertedFrameBufferSize = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_BGR24, _finalSize.Width, _finalSize.Height, 1); pConvertedFrameBuffer = Marshal.AllocHGlobal(convertedFrameBufferSize); ffmpeg.av_image_fill_arrays(ref dstData, ref dstLinesize, (byte *)pConvertedFrameBuffer, AVPixelFormat.AV_PIX_FMT_BGR24, _finalSize.Width, _finalSize.Height, 1); pConvertContext = ffmpeg.sws_getContext(_videoCodecContext->width, _videoCodecContext->height, NormalizePixelFormat(srcFmt), _finalSize.Width, _finalSize.Height, AVPixelFormat.AV_PIX_FMT_BGR24, ffmpeg.SWS_FAST_BILINEAR, null, null, null); } Log("SWS_SCALE", ffmpeg.sws_scale(pConvertContext, vf->data, vf->linesize, 0, _videoCodecContext->height, dstData, dstLinesize)); if (vf->decode_error_flags > 0) { ffmpeg.av_frame_free(&vf); break; } using ( var mat = new Bitmap(_finalSize.Width, _finalSize.Height, dstLinesize[0], PixelFormat.Format24bppRgb, pConvertedFrameBuffer)) { var nfe = new NewFrameEventArgs(mat); nf.Invoke(this, nfe); } _lastVideoFrame = DateTime.UtcNow; ffmpeg.av_frame_free(&vf); break; } ffmpeg.av_frame_free(&vf); } while (ret == 0); } if (nf != null && _videoStream != null) { if ((DateTime.UtcNow - _lastVideoFrame).TotalMilliseconds * 1000 > _timeoutMicroSeconds) { _res = ReasonToFinishPlaying.DeviceLost; _abort = true; } } ffmpeg.av_packet_unref(&packet); if (ret == -11) { Thread.Sleep(10); } } while (!_abort && !MainForm.ShuttingDown); NewFrame?.Invoke(this, new NewFrameEventArgs(null)); CleanUp(); }
private void ReadFrames() { var pConvertedFrameBuffer = IntPtr.Zero; SwsContext *pConvertContext = null; var audioInited = false; var videoInited = false; byte[] buffer = null, tbuffer = null; var dstData = new byte_ptrArray4(); var dstLinesize = new int_array4(); BufferedWaveProvider waveProvider = null; SampleChannel sampleChannel = null; var packet = new AVPacket(); do { ffmpeg.av_init_packet(&packet); if (_audioCodecContext != null && buffer == null) { buffer = new byte[_audioCodecContext->sample_rate * 2]; tbuffer = new byte[_audioCodecContext->sample_rate * 2]; } if (Log("AV_READ_FRAME", ffmpeg.av_read_frame(_formatContext, &packet))) { break; } if ((packet.flags & ffmpeg.AV_PKT_FLAG_CORRUPT) == ffmpeg.AV_PKT_FLAG_CORRUPT) { break; } var nf = NewFrame; var da = DataAvailable; _lastPacket = DateTime.UtcNow; int ret; if (_audioStream != null && packet.stream_index == _audioStream->index && _audioCodecContext != null) { if (HasAudioStream != null) { HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; } if (da != null) { var s = 0; fixed(byte **outPtrs = new byte *[32]) { fixed(byte *bPtr = &tbuffer[0]) { outPtrs[0] = bPtr; ffmpeg.avcodec_send_packet(_audioCodecContext, &packet); do { ret = ffmpeg.avcodec_receive_frame(_audioCodecContext, _audioFrame); if (ret == 0) { var dat = _audioFrame->data[0]; var numSamplesOut = ffmpeg.swr_convert(_swrContext, outPtrs, _audioCodecContext->sample_rate, &dat, _audioFrame->nb_samples); var l = numSamplesOut * 2 * _audioCodecContext->channels; Buffer.BlockCopy(tbuffer, 0, buffer, s, l); s += l; } if (_audioFrame->decode_error_flags > 0) { break; } } while (ret == 0); if (s > 0) { var ba = new byte[s]; Buffer.BlockCopy(buffer, 0, ba, 0, s); if (!audioInited) { audioInited = true; RecordingFormat = new WaveFormat(_audioCodecContext->sample_rate, 16, _audioCodecContext->channels); waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(500) }; sampleChannel = new SampleChannel(waveProvider); sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; } waveProvider.AddSamples(ba, 0, s); var sampleBuffer = new float[s]; var read = sampleChannel.Read(sampleBuffer, 0, s); da(this, new DataAvailableEventArgs(ba, read)); if (Listening) { WaveOutProvider?.AddSamples(ba, 0, read); } } } } } } if (nf != null && _videoStream != null && packet.stream_index == _videoStream->index && _videoCodecContext != null) { ffmpeg.avcodec_send_packet(_videoCodecContext, &packet); do { ret = ffmpeg.avcodec_receive_frame(_videoCodecContext, _videoFrame); if (ret == 0 && EmitFrame) { if (!videoInited) { videoInited = true; var convertedFrameBufferSize = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_BGR24, _videoCodecContext->width, _videoCodecContext->height, 1); pConvertedFrameBuffer = Marshal.AllocHGlobal(convertedFrameBufferSize); ffmpeg.av_image_fill_arrays(ref dstData, ref dstLinesize, (byte *)pConvertedFrameBuffer, AVPixelFormat.AV_PIX_FMT_BGR24, _videoCodecContext->width, _videoCodecContext->height, 1); pConvertContext = ffmpeg.sws_getContext(_videoCodecContext->width, _videoCodecContext->height, _videoCodecContext->pix_fmt, _videoCodecContext->width, _videoCodecContext->height, AVPixelFormat.AV_PIX_FMT_BGR24, ffmpeg.SWS_FAST_BILINEAR, null, null, null); } Log("SWS_SCALE", ffmpeg.sws_scale(pConvertContext, _videoFrame->data, _videoFrame->linesize, 0, _videoCodecContext->height, dstData, dstLinesize)); if (_videoFrame->decode_error_flags > 0) { break; } using ( var mat = new Bitmap(_videoCodecContext->width, _videoCodecContext->height, dstLinesize[0], PixelFormat.Format24bppRgb, pConvertedFrameBuffer)) { var nfe = new NewFrameEventArgs(mat); nf.Invoke(this, nfe); } _lastVideoFrame = DateTime.UtcNow; } } while (ret == 0); } if (nf != null && _videoStream != null) { if ((DateTime.UtcNow - _lastVideoFrame).TotalMilliseconds > _timeout) { _res = ReasonToFinishPlaying.DeviceLost; _abort = true; } } ffmpeg.av_packet_unref(&packet); } while (!_abort && !MainForm.ShuttingDown); NewFrame?.Invoke(this, new NewFrameEventArgs(null)); try { Program.MutexHelper.Wait(); if (pConvertedFrameBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pConvertedFrameBuffer); } if (_formatContext != null) { if (_formatContext->streams != null) { var j = (int)_formatContext->nb_streams; for (var i = j - 1; i >= 0; i--) { var stream = _formatContext->streams[i]; if (stream != null && stream->codec != null && stream->codec->codec != null) { stream->discard = AVDiscard.AVDISCARD_ALL; ffmpeg.avcodec_close(stream->codec); } } } fixed(AVFormatContext **f = &_formatContext) { ffmpeg.avformat_close_input(f); } _formatContext = null; } if (_videoFrame != null) { fixed(AVFrame **pinprt = &_videoFrame) { ffmpeg.av_frame_free(pinprt); _videoFrame = null; } } if (_audioFrame != null) { fixed(AVFrame **pinprt = &_audioFrame) { ffmpeg.av_frame_free(pinprt); _audioFrame = null; } } _videoStream = null; _audioStream = null; _audioCodecContext = null; _videoCodecContext = null; if (_swrContext != null) { fixed(SwrContext **s = &_swrContext) { ffmpeg.swr_free(s); } _swrContext = null; } if (pConvertContext != null) { ffmpeg.sws_freeContext(pConvertContext); } if (sampleChannel != null) { sampleChannel.PreVolumeMeter -= SampleChannelPreVolumeMeter; sampleChannel = null; } } catch (Exception ex) { Logger.LogException(ex, "Media Stream (close)"); } finally { try { Program.MutexHelper.Release(); } catch { } } PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res)); AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res)); }
private void ReadFrames() { pConvertedFrameBuffer = IntPtr.Zero; pConvertContext = null; var audioInited = false; var videoInited = false; byte[] buffer = null, tbuffer = null; var dstData = new byte_ptrArray4(); var dstLinesize = new int_array4(); BufferedWaveProvider waveProvider = null; sampleChannel = null; var packet = new AVPacket(); do { ffmpeg.av_init_packet(&packet); if (_audioCodecContext != null && buffer == null) { buffer = new byte[_audioCodecContext->sample_rate * 2]; tbuffer = new byte[_audioCodecContext->sample_rate * 2]; } if (Log("AV_READ_FRAME", ffmpeg.av_read_frame(_formatContext, &packet))) { break; } if ((packet.flags & ffmpeg.AV_PKT_FLAG_CORRUPT) == ffmpeg.AV_PKT_FLAG_CORRUPT) { break; } var nf = NewFrame; var da = DataAvailable; _lastPacket = DateTime.UtcNow; int ret = -11; //EAGAIN if (_audioStream != null && packet.stream_index == _audioStream->index && _audioCodecContext != null) { if (HasAudioStream != null) { HasAudioStream?.Invoke(this, EventArgs.Empty); HasAudioStream = null; } if (da != null) { var s = 0; fixed(byte **outPtrs = new byte *[32]) { fixed(byte *bPtr = &tbuffer[0]) { outPtrs[0] = bPtr; ffmpeg.avcodec_send_packet(_audioCodecContext, &packet); do { ret = ffmpeg.avcodec_receive_frame(_audioCodecContext, _audioFrame); if (ret == 0) { fixed(byte **datptr = _audioFrame->data.ToArray()) { var numSamplesOut = ffmpeg.swr_convert(_swrContext, outPtrs, _audioCodecContext->sample_rate, datptr, _audioFrame->nb_samples); if (numSamplesOut > 0) { var l = numSamplesOut * 2 * OutFormat.Channels; Buffer.BlockCopy(tbuffer, 0, buffer, s, l); s += l; } else { ret = numSamplesOut; //(error) } } } if (_audioFrame->decode_error_flags > 0) { break; } } while (ret == 0); if (s > 0) { var ba = new byte[s]; Buffer.BlockCopy(buffer, 0, ba, 0, s); if (!audioInited) { audioInited = true; RecordingFormat = new WaveFormat(_audioCodecContext->sample_rate, 16, _audioCodecContext->channels); waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(200) }; sampleChannel = new SampleChannel(waveProvider); sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; } waveProvider.AddSamples(ba, 0, s); var sampleBuffer = new float[s]; var read = sampleChannel.Read(sampleBuffer, 0, s); da(this, new DataAvailableEventArgs(ba, s)); if (Listening) { WaveOutProvider?.AddSamples(ba, 0, read); } } } } } } if (nf != null && _videoStream != null && packet.stream_index == _videoStream->index && _videoCodecContext != null) { ffmpeg.avcodec_send_packet(_videoCodecContext, &packet); do { ret = ffmpeg.avcodec_receive_frame(_videoCodecContext, _videoFrame); var ef = EmitFrame; //Debug.WriteLine("ret: "+ret+", ef:"+ef); if (ret == 0 && ef) { if (!videoInited) { videoInited = true; var convertedFrameBufferSize = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_BGR24, _videoCodecContext->width, _videoCodecContext->height, 1); pConvertedFrameBuffer = Marshal.AllocHGlobal(convertedFrameBufferSize); ffmpeg.av_image_fill_arrays(ref dstData, ref dstLinesize, (byte *)pConvertedFrameBuffer, AVPixelFormat.AV_PIX_FMT_BGR24, _videoCodecContext->width, _videoCodecContext->height, 1); pConvertContext = ffmpeg.sws_getContext(_videoCodecContext->width, _videoCodecContext->height, _videoCodecContext->pix_fmt, _videoCodecContext->width, _videoCodecContext->height, AVPixelFormat.AV_PIX_FMT_BGR24, ffmpeg.SWS_FAST_BILINEAR, null, null, null); } Log("SWS_SCALE", ffmpeg.sws_scale(pConvertContext, _videoFrame->data, _videoFrame->linesize, 0, _videoCodecContext->height, dstData, dstLinesize)); if (_videoFrame->decode_error_flags > 0) { break; } using ( var mat = new Bitmap(_videoCodecContext->width, _videoCodecContext->height, dstLinesize[0], PixelFormat.Format24bppRgb, pConvertedFrameBuffer)) { var nfe = new NewFrameEventArgs(mat); nf.Invoke(this, nfe); } _lastVideoFrame = DateTime.UtcNow; } } while (ret == 0); } if (nf != null && _videoStream != null) { if ((DateTime.UtcNow - _lastVideoFrame).TotalMilliseconds * 1000 > _timeoutMicroSeconds) { _res = ReasonToFinishPlaying.DeviceLost; _abort = true; } } ffmpeg.av_packet_unref(&packet); if (ret == -11) { Thread.Sleep(10); } } while (!_abort && !MainForm.ShuttingDown); NewFrame?.Invoke(this, new NewFrameEventArgs(null)); CleanUp(); }