Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FFmpeg error with Logitech C925e #48

Open
TJYSunset opened this issue May 24, 2023 · 2 comments
Open

FFmpeg error with Logitech C925e #48

TJYSunset opened this issue May 24, 2023 · 2 comments

Comments

@TJYSunset
Copy link

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

@Speykious
Copy link
Owner

...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.

@TJYSunset
Copy link
Author

TJYSunset commented May 25, 2023

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 calls Stream.ReadExactlyAsync() or Stream.ReadAsync() and won't work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants