webcam-capture-driver-native icon indicating copy to clipboard operation
webcam-capture-driver-native copied to clipboard

Can't display camera stream on some resolutions on Windows

Open Rizen59 opened this issue 8 months ago • 9 comments

Hi @eduramiba,

I just tested the project and have some issues on Windows 10, not MacOS. Same on a colleage laptop. I ran TestDriver.java from the project. It does not display anything.

What I notice is it works with a resolution of 160x120, 320x180, 320x240 but not beyond.

Here are the logs when I switched to 160*120, then the ones in 640 * 480

14:40:02.784 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Closing webcam Integrated Webcam
14:40:02.784 [atomic-processor-1] INFO com.github.sarxos.webcam.ds.cgt.WebcamCloseTask -- Closing Integrated Webcam
INFO_LEVEL: SessionProcessor: stopCapture - capture is stopped!!!  Error code: 0000000000, Description: Success with the result.
INFO_LEVEL: SessionProcessor: closeSession - session is closed!!!  Error code: 0000000000, Description: Success with the result.
14:40:03.073 [Thread-7] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- invoke with (aCallEventCode, aSessionDescriptor) = (7, 1)
14:40:03.074 [Thread-8] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- invoke with (aCallEventCode, aSessionDescriptor) = (9, 1)
14:40:03.079 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Webcam Integrated Webcam has been closed
14:40:03.079 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Setting new resolution 160x120
14:40:03.080 [atomic-processor-1] INFO com.github.sarxos.webcam.ds.cgt.WebcamOpenTask -- Opening webcam Integrated Webcam
14:40:03.080 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerVideoDevice -- Media types for resolution 160x120 = [CaptureManagerMediaType{width=160, height=120, majorType=MFMediaType_Video, subType=MFVideoFormat_YUY2}]
14:40:03.080 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerVideoDevice -- Media types for resolution 160x120 = [CaptureManagerMediaType{width=160, height=120, majorType=MFMediaType_Video, subType=MFVideoFormat_YUY2}]
14:40:03.081 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerVideoDevice -- Using video media type: CaptureManagerMediaType{width=160, height=120, majorType=MFMediaType_Video, subType=MFVideoFormat_YUY2}
INFO_LEVEL: SessionProcessor: setTopology - topology is ready!!!  Error code: 0000000000, Description: Success with the result.
14:40:03.210 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- Successfully created CallSessionControl
INFO_LEVEL: SessionProcessor: startCapture - capture is started!!!  Error code: 0000000000, Description: Success with the result.
14:40:03.356 [Thread-9] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- invoke with (aCallEventCode, aSessionDescriptor) = (5, 2)
14:40:03.355 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Webcam is now open Integrated Webcam
14:40:21.155 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Closing webcam Integrated Webcam
14:40:21.155 [atomic-processor-1] INFO com.github.sarxos.webcam.ds.cgt.WebcamCloseTask -- Closing Integrated Webcam
INFO_LEVEL: SessionProcessor: stopCapture - capture is stopped!!!  Error code: 0000000000, Description: Success with the result.
INFO_LEVEL: SessionProcessor: closeSession - session is closed!!!  Error code: 0000000000, Description: Success with the result.
14:40:21.444 [Thread-10] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- invoke with (aCallEventCode, aSessionDescriptor) = (7, 2)
14:40:21.444 [Thread-11] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- invoke with (aCallEventCode, aSessionDescriptor) = (9, 2)
14:40:21.446 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Webcam Integrated Webcam has been closed
14:40:21.446 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Setting new resolution 640x480
14:40:21.446 [atomic-processor-1] INFO com.github.sarxos.webcam.ds.cgt.WebcamOpenTask -- Opening webcam Integrated Webcam
14:40:21.446 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerVideoDevice -- Media types for resolution 640x480 = [CaptureManagerMediaType{width=640, height=480, majorType=MFMediaType_Video, subType=MFVideoFormat_NV12}, CaptureManagerMediaType{width=640, height=480, majorType=MFMediaType_Video, subType=MFVideoFormat_MJPG}, CaptureManagerMediaType{width=640, height=480, majorType=MFMediaType_Video, subType=MFVideoFormat_YUY2}]
14:40:21.446 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerVideoDevice -- Media types for resolution 640x480 = [CaptureManagerMediaType{width=640, height=480, majorType=MFMediaType_Video, subType=MFVideoFormat_NV12}]
14:40:21.446 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerVideoDevice -- Using video media type: CaptureManagerMediaType{width=640, height=480, majorType=MFMediaType_Video, subType=MFVideoFormat_NV12}
INFO_LEVEL: SessionProcessor: setTopology - topology is ready!!!  Error code: 0000000000, Description: Success with the result.
14:40:21.548 [atomic-processor-1] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- Successfully created CallSessionControl
INFO_LEVEL: SessionProcessor: startCapture - capture is started!!!  Error code: 0000000000, Description: Success with the result.
14:40:21.722 [JavaFX Application Thread] DEBUG com.github.sarxos.webcam.Webcam -- Webcam is now open Integrated Webcam
14:40:21.722 [Thread-12] INFO com.github.eduramiba.webcamcapture.drivers.capturemanager.CaptureManagerFrameGrabberSession -- invoke with (aCallEventCode, aSessionDescriptor) = (5, 3)

What should I check to have more information? Have you ever notice this problem?

Here is the code used to add a resolution choice box. Also notice that camera.close() is not enough to close the camera. It must be followed by dispose().

package com.github.eduramiba.webcamcapture;

import com.github.eduramiba.webcamcapture.drivers.NativeDriver;
import com.github.eduramiba.webcamcapture.drivers.WebcamDeviceWithBufferOperations;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamDevice;

import java.awt.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.github.sarxos.webcam.WebcamResolution;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestDriver extends Application {

    private static final Logger LOG = LoggerFactory.getLogger(TestDriver.class);

    public static final ScheduledExecutorService EXECUTOR = Executors.newScheduledThreadPool(4);

    public static void main(String[] args) {
        Webcam.setDriver(new NativeDriver());

        launch(args);
    }

    public void changeResolution(Webcam camera, Dimension dimension) {
        camera.close();
        camera.getDevice().dispose();
        camera.setViewSize(dimension);
        camera.open();
    }

    @Override
    public void start(Stage stage) throws Exception {
        final ImageView imageView = new ImageView();
        final ChoiceBox<Dimension> resolutionChoiceBox = new ChoiceBox<>();
        resolutionChoiceBox.setConverter(new StringConverter<>() {

            @Override
            public String toString(Dimension dimension) {
                return dimension != null ? dimension.width + " x " + dimension.height : null;
            }

            @Override
            public Dimension fromString(String s) {
                return null;
            }
        });
        final HBox root = new HBox();
        root.getChildren().addAll(imageView, resolutionChoiceBox);

        Webcam.getWebcams().stream()
                .findFirst()
                .ifPresent((final Webcam camera) -> {
                    final WebcamDevice device = camera.getDevice();

                    resolutionChoiceBox.setItems(FXCollections.observableArrayList(device.getResolutions()));
                    camera.setViewSize(WebcamResolution.QVGA.getSize());
                    resolutionChoiceBox.getSelectionModel().select(WebcamResolution.QVGA.getSize());
                    resolutionChoiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Dimension>() {
                        @Override
                        public void changed(ObservableValue<? extends Dimension> observableValue, Dimension oldValue, Dimension newValue) {
                            changeResolution(camera, newValue);
                        }
                    });

                    LOG.info("Found camera: {}, device = {}", camera, device);

                    final int width = device.getResolution().width;
                    final int height = device.getResolution().height;
                    final WritableImage fxImage = new WritableImage(width, height);
                    Platform.runLater(() -> {
                        imageView.setImage(fxImage);
                        stage.setWidth(width + 100);
                        stage.setHeight(height + 100);
                        stage.centerOnScreen();
                    });

                    camera.getLock().disable();
                    camera.open();
                    if (device instanceof WebcamDeviceWithBufferOperations) {
                        final WebcamDeviceWithBufferOperations dev = ((WebcamDeviceWithBufferOperations) device);
                        EXECUTOR.scheduleAtFixedRate(new Runnable() {
                            private long lastFrameTimestamp = -1;

                            @Override
                            public void run() {
                                if (dev.updateFXIMage(fxImage, lastFrameTimestamp)) {
                                    lastFrameTimestamp = dev.getLastFrameTimestamp();
                                }

                            }
                        }, 0, 16, TimeUnit.MILLISECONDS);
                    }
                });

        stage.setOnCloseRequest(t -> {
            Platform.exit();
            System.exit(0);
        });

        // Create the Scene
        final Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Webcam example");
        stage.show();
    }
}

Thanks for your feedback, and your great work ;)

Rizen59 avatar Jun 19 '24 13:06 Rizen59