-1

我从摄像头编写 Windows 服务女巫解码视频流。我用 FFMPEG.Autogen 包装器将它写在 c# 上。

当我将它作为服务运行时,我的问题是“AccessViolationException”。如果我将应用程序作为控制台应用程序运行,我没有例外。

在 Stacktrace 我看到这个:

в FFmpeg.AutoGen.ffmpeg+<>c.<.cctor>b__5_572(FFmpeg.AutoGen.AVFrame*, FFmpeg.AutoGen.AVFrame*, Int32)
в FFmpeg.AutoGen.ffmpeg.av_hwframe_transfer_data(FFmpeg.AutoGen.AVFrame*, FFmpeg.AutoGen.AVFrame*,Int32)
в VideoProviderService.VideoSources.RTSPVideoSource.TryDecodeNextFrame(Boolean ByRef)

TryDecodeNextFrame 方法的代码:

public IntPtr TryDecodeNextFrame(out bool state)
{
    try
    {
        ffmpeg.av_frame_unref(pFrame);
        ffmpeg.av_frame_unref(cpuFrame);
        int error;
        do
        {
            try
            {
                do
                {
                    timeout = DateTime.Now.AddSeconds(2);
                    error = ffmpeg.av_read_frame(_pFormatContext, pPacket);
                    if (error == ffmpeg.AVERROR_EOF)
                    {
                        state = false;
                        return IntPtr.Zero;
                    }
                    error.ThrowExceptionIfError();
                } while (pPacket->stream_index != _streamIndex);
                ffmpeg.avcodec_send_packet(pCodecContext, pPacket).ThrowExceptionIfError();
            }
            finally
            {
                ffmpeg.av_packet_unref(pPacket);
            }
            error = ffmpeg.avcodec_receive_frame(pCodecContext, pFrame);
        } while (error == ffmpeg.AVERROR(ffmpeg.EAGAIN));
        error.ThrowExceptionIfError();
        ffmpeg.av_hwframe_transfer_data(cpuFrame, pFrame, 0).ThrowExceptionIfError();
        ptrToFrame = (IntPtr)vfc.Convert(*cpuFrame).data[0];  
    }
    catch
    {
        state = false;
        return IntPtr.Zero;
    }
    state = true;
    return ptrToFrame;
}

我试图做的事情:

  1. 我检查了av_hwframe_transfer_data.
  2. 我更改了服务的用户。
  3. 我尝试编译为 x86 或 x64 配置。

我不知道如何解决这个问题。有人有想法吗?

4

1 回答 1

0

您似乎没有正确处理您的帧(pFrame/cpuFrame)。特别是对于 cpuFrame,您应该在每次运行时分配它并在每次运行结束时释放它。此外,对于 pFrame,您应该在 av_hw_frame_transfer_data 之后直接取消引用它。例如:-

cpuFrame = ffmpeg.av_frame_alloc();

....

ffmpeg.av_hwframe_transfer_data(cpuFrame, pFrame, 0).ThrowExceptionIfError();

ffmpeg.av_frame_unref(pFrame);

.... Process your cpuFrame ...

ffmpeg.av_frame_free(&cpuFrame);

....
于 2019-11-08T18:06:30.880 回答