nyanmisaka / ffmpeg-rockchip

FFmpeg with async and zero-copy Rockchip MPP & RGA support
Other
325 stars 47 forks source link

`Internal bug, should not have happened` 在同时编码与解码的时候 #45

Closed Coloryr closed 2 months ago

Coloryr commented 3 months ago
System.ApplicationException: Internal bug, should not have happened
   at IPHost.Desktop.FFmpegHelper.ThrowExceptionIfError(Int32 error) in E:\code\IPHost\IPHost.Desktop\FFmpegHelper.cs:line 76
   at IPHost.Desktop.VideoDecoder.<.ctor>b__28_0() in E:\code\IPHost\IPHost.Desktop\VideoDecoder.cs:line 192
Aborted
if (packs.TryDequeue(out var packet))
{
    var data = (byte*)ffmpeg.av_malloc((ulong)packet.Size);
    Marshal.Copy(packet.Data, 0, (IntPtr)data, packet.Size);

    ffmpeg.av_packet_from_data(_pPacket, data, packet.Size)
        .ThrowExceptionIfError();

    ffmpeg.avcodec_send_packet(_videoCodecContext, _pPacket)
        .ThrowExceptionIfError();

    //ffmpeg.av_packet_unref(_pPacket);
    ffmpeg.av_free(data);

    error = ffmpeg.avcodec_receive_frame(_videoCodecContext, _videoFrame);
    if (error == 0)
    {
        AVFrame frame = *_videoFrame;

        if (_videoCodecContext->hw_device_ctx != null)
        {
            ffmpeg.av_hwframe_transfer_data(_receivedFrame, _videoFrame, 0)
                .ThrowExceptionIfError();
            frame = *_receivedFrame;
            if (first_frame)
            {
                first_frame = false;
            }
        }

        if (vfc == null)
        {
            var sourceSize = FrameSize;
            var sourcePixelFormat = HWDeviceType == AVHWDeviceType.AV_HWDEVICE_TYPE_NONE
            ? _videoCodecContext->pix_fmt
                     : DecodeHelper.GetHWPixelFormat(HWDeviceType);
            var destinationSize = sourceSize;
            var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_BGRA;
            vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat);
        }

        var convertedFrame = vfc.Convert(frame);
        IPHostApi.SetVideoPtr(_uuid, convertedFrame.width, convertedFrame.height, (IntPtr)convertedFrame.data[0]);

        start_time = ffmpeg.av_gettime() - ffmpeg.av_rescale_q(_videoFrame->pts, TimeBase, ffmpeg.av_make_q(1, ffmpeg.AV_TIME_BASE));
    }
    else if (error != -11)
    {
        error.ThrowExceptionIfError();
    }
}
else
{
    Thread.Sleep(1);
}
Coloryr commented 3 months ago

如果只是单一编码或者解码没这个问题,而且这个问题是概率发生 问题发生在avcodec_receive_frame

nyanmisaka commented 3 months ago

Not reproducible via FFmpeg CLI transcoding. More information is needed to locate which line in FFmpeg is throwing this error AVERROR_BUG. There's indeed one in rkmppdec.c but it is used as an assertion.

nyanmisaka commented 2 months ago

The problem cannot be reproduced through the CLI. My guess is that in the downstream application, the encoder takes up too many slots in the decoder buffer pool and the decoder is stuck.