Я хочу декодировать поток и отправить его в растровое изображение, чтобы отобразить окно изображения без его кодирования. >
Видео по RTSP воспроизводится нормально.
Однако мои видео часто прерываются.
Иногда изображение становится серым, а затем появляется назад, или экран выглядит так, как будто какая-то часть сломана и размыто.
Я подтвердил, что кадр пришел правильно, но есть несколько гипотез, проблема ли это в декодированных данных или потому, что они выполняются асинхронно, но я не узнайте подробную причину.
Пожалуйста, помогите мне.
это мой код
Код: Выделить всё
private async void DecodeAllFramesToImages(AVHWDeviceType HWDevice, string rtspUrl)
{
await Task.Run(async() =>
{
var url = rtspUrl;
using var vsd = new VideoStreamDecoder(url);
var info = vsd.GetContextInfo();
info.ToList().ForEach(x => Console.WriteLine($"{x.Key} = {x.Value}"));
var sourceSize = vsd.FrameSize;
var sourcePixelFormat = HWDevice == AVHWDeviceType.AV_HWDEVICE_TYPE_NONE
? vsd.PixelFormat
: GetHWPixelFormat(HWDevice);
var destinationSize = sourceSize;
var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_BGR24;
Debug.WriteLine(url + " " + sourceSize);
using var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat);
while (vsd.TryDecodeNextFrame(out var frame))
{
if (stopRecord)
break;
var convertedFrame = vfc.Convert(frame);
Bitmap image = null;
// Create image without using unsafe block
unsafe
{
image = new Bitmap(convertedFrame.width, convertedFrame.height, convertedFrame.linesize[0], PixelFormat.Format24bppRgb, (IntPtr)convertedFrame.data[0]);
}
await Task.Run(() => UpdatePictureBox(image));
}
});
}
public bool TryDecodeNextFrame(out AVFrame frame)
{
ffmpeg.av_frame_unref(_pFrame);
ffmpeg.av_frame_unref(_receivedFrame);
int error;
do
{
try
{
do
{
ffmpeg.av_packet_unref(_pPacket);
error = ffmpeg.av_read_frame(_pFormatContext, _pPacket);
if (error == ffmpeg.AVERROR_EOF)
{
frame = *_pFrame;
return false;
}
error.ThrowExceptionIfError();
} while (_pPacket->stream_index != _streamIndex);
ffmpeg.avcodec_send_packet(_pCodecContext, _pPacket).ThrowExceptionIfError();
}
catch(Exception ex)
{
Debug.WriteLine("UC_MPP.VideoStreamingDecoder.TryDecodeNextFrame : " + ex.Message);
}
finally
{
ffmpeg.av_packet_unref(_pPacket);
}
error = ffmpeg.avcodec_receive_frame(_pCodecContext, _pFrame);
} while (error == ffmpeg.AVERROR(ffmpeg.EAGAIN));
error.ThrowExceptionIfError();
if (_pCodecContext->hw_device_ctx != null)
{
ffmpeg.av_hwframe_transfer_data(_receivedFrame, _pFrame, 0).ThrowExceptionIfError();
frame = *_receivedFrame;
}
else
frame = *_pFrame;
return true;
}
public AVFrame Convert(AVFrame sourceFrame)
{
ffmpeg.sws_scale(_pConvertContext,
sourceFrame.data,
sourceFrame.linesize,
0,
sourceFrame.height,
_dstData,
_dstLinesize);
var data = new byte_ptr8();
data.UpdateFrom(_dstData);
var linesize = new int8();
linesize.UpdateFrom(_dstLinesize);
return new AVFrame
{
data = data,
linesize = linesize,
width = _destinationSize.Width,
height = _destinationSize.Height
};
}
Подробнее здесь: https://stackoverflow.com/questions/776 ... tly-broken