Почему я ловлю исключение «AccessViolationException» в av_hwframe_transfer_data (), когда я запускаю его как службу Windows? - PullRequest
0 голосов
/ 31 октября 2019

Пишу сервис Windows с декодированием видеопотока с камеры. Я пишу это на C # с FFMPEG.Autogen оберткой.

Моя проблема "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.

Я понятия не имею, как решить эту проблему. У кого-нибудь есть мысли?

1 Ответ

0 голосов
/ 08 ноября 2019

Похоже, вы неправильно обрабатываете свои кадры (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);

....
...