SeeShark
SeeShark copied to clipboard
FFmpeg error with Logitech C925e
Initializing camera with default settings
When initializing the camera without an explicit format requirement, I get the following exception on calling TryGetFrame()
:
System.ApplicationException: End of file
at SeeShark.FFmpeg.FFmpegHelper.ThrowExceptionIfError(Int32 error)
at SeeShark.Decode.VideoStreamDecoder.TryDecodeNextFrame(Frame& nextFrame)
at SeeShark.Device.VideoDevice.TryGetFrame(Frame& frame)
at <MY CODE>
Soon the program would crash with another ApplicationException
:
Unhandled exception. System.ApplicationException: Invalid data found when processing input
at SeeShark.FFmpeg.FFmpegHelper.ThrowExceptionIfError(Int32 error)
at SeeShark.Decode.VideoStreamDecoder.TryDecodeNextFrame(Frame& nextFrame)
at SeeShark.Device.VideoDevice.TryGetFrame(Frame& frame)
at SeeShark.Device.VideoDevice.DecodeLoop()
Initialization code
var cameraInfo = CameraManager.Devices.FirstOrDefault(
x => x.Name?.Contains(cameraNameSegment) ?? false
);
if (ReferenceEquals(cameraInfo, null))
return;
Camera = CameraManager.GetDevice(cameraInfo);
Camera.StartCapture();
Initializing with yuyv422
640x480
If I instead specify the format to be yuyv422 640x480 (I already dumped AvailableVideoInputOptions
so I know for sure it's supported), GetDevice()
will fail with the following:
System.ApplicationException: I/O error
at SeeShark.FFmpeg.FFmpegHelper.ThrowExceptionIfError(Int32 error)
at SeeShark.Decode.VideoStreamDecoder..ctor(String url, AVInputFormat* inputFormat, IDictionary`2 options)
at SeeShark.Device.VideoDevice..ctor(VideoDeviceInfo info, DeviceInputFormat inputFormat, VideoInputOptions options)
at SeeShark.Device.CameraManager.GetDevice(CameraInfo info, VideoInputOptions options)
at <MY CODE>
Initialization code
Camera = CameraManager.GetDevice(
cameraInfo,
cameraInfo.AvailableVideoInputOptions!.First(
x => x.InputFormat == "yuyv422" && x.VideoSize == (640, 480)
)
);
Initializing with mjpeg
640x480
Interestingly, using mjpeg
will throw a different exception:
System.ApplicationException: Invalid argument
at SeeShark.FFmpeg.FFmpegHelper.ThrowExceptionIfError(Int32 error)
at SeeShark.Decode.VideoStreamDecoder..ctor(String url, AVInputFormat* inputFormat, IDictionary`2 options)
at SeeShark.Decode.VideoStreamDecoder..ctor(String url, DeviceInputFormat inputFormat, IDictionary`2 options)
at SeeShark.Device.VideoDevice..ctor(VideoDeviceInfo info, DeviceInputFormat inputFormat, VideoInputOptions options)
at SeeShark.Device.Camera..ctor(VideoDeviceInfo info, DeviceInputFormat inputFormat, VideoInputOptions options)
at SeeShark.Device.CameraManager.GetDevice(CameraInfo info, VideoInputOptions options)
at <MY CODE>
Initialization code
Camera = CameraManager.GetDevice(
cameraInfo,
cameraInfo.AvailableVideoInputOptions!.First(
x => x.InputFormat == "mjpeg" && x.VideoSize == (640, 480)
)
);
Initializing with yuyv422
1920x1080
... And if I use the full resolution the program crashes with a memory error...
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at FFmpeg.AutoGen.ffmpeg.av_read_frame(FFmpeg.AutoGen.AVFormatContext*, FFmpeg.AutoGen.AVPacket*)
at SeeShark.Decode.VideoStreamDecoder.TryDecodeNextFrame(SeeShark.Frame ByRef)
at SeeShark.Device.VideoDevice.TryGetFrame(SeeShark.Frame ByRef)
at SeeShark.Device.VideoDevice.DecodeLoop()
Maybe another minor issue?
Also unrelated, but Microsoft officially discourages the use of ApplicationException
.
Environment Info
Windows 11 22H2 (22621.963)
Logitech C925e
net7.0 with Microsoft.NET.Sdk.Web
, AnyCPU or x64, Debug or Release
prebuilt FFmpeg binaries from https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2023-05-23-12-46/ffmpeg-n5.1.3-10-g33ed503e59-win64-gpl-shared-5.1.zip or https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-5.1.2-full_build-shared.7z
...Well that's really weird... A different error each time. And the error messages don't help.
I need to do something about it. I have no clue if I can fix this bug though. I still don't have any Windows installation.
Also thanks, didn't know they discouraged ApplicationException
.
For the time being, I switched to calling FFmpeg directly using rosenbjerg/FFMpegCore, and it works perfectly fine as long as I'm using their StreamPipeSink
instead of implementing my own IPipeSink
(which FFmpeg fails with av_interleaved_write_frame(): Invalid argument
etc etc):
var args = FFMpegArguments
.FromDeviceInput("video=\"Logitech Webcam C925e\"", a => a.ForceFormat("dshow"))
.OutputToPipe(
new StreamPipeSink(FrameStream),
a =>
a.WithVideoCodec("rawvideo")
.ForceFormat("rawvideo")
.WithCustomArgument("-pix_fmt rgb24")
.WithVideoFilters(f => f.Scale(new Size(640, 480)))
.WithFramerate(12)
)
.WithLogLevel(FFMpegLogLevel.Info);
Log.Information("{Args}", args.Arguments);
args.ProcessSynchronously();
The code above produces the following command line arguments:
-f dshow -i video="Logitech Webcam C925e" -c:v rawvideo -f rawvideo -pix_fmt rgb24 -vf "scale=640:480" -r 12 "\\.\pipe\FFMpegCore_4c4d8" -y
I know it's too vague but I'm exhausted to find the root cause myself, so hope this info somewhat helps?
Some quick Ctrl+LMB's:
- They create named pipes as seen here
- And call
Stream.CopyToAsync()
as seen here- My
IPipeSink
implementation callsStream.ReadExactlyAsync()
orStream.ReadAsync()
and won't work
- My