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

Error on libobs reset video: -3 (Invalid Parameter) #3

Open
Osiris-Team opened this issue Jul 11, 2024 · 1 comment
Open

Error on libobs reset video: -3 (Invalid Parameter) #3

Osiris-Team opened this issue Jul 11, 2024 · 1 comment

Comments

@Osiris-Team
Copy link

Osiris-Team commented Jul 11, 2024

@lulzsun
I am currently porting this bad boy over to Java and encountering the error above.
Any help would be really appreciated!
Log:

libobs version: 29.1.2
info: CPU Name: AMD Ryzen 9 5950X 16-Core Processor            
info: CPU Speed: 3400MHz
info: Physical Cores: 16, Logical Cores: 32
info: Physical Memory: 16308MB Total, 2991MB Free
info: Windows Version: 10.0 Build 22631 (release: 23H2; revision: 3880; 64-bit)
info: Running as administrator: false
info: Windows 10/11 Gaming Features:
info: 	Game DVR: On
info: 	Game Mode: Probably On (no reg key set)
info: Sec. Software Status:
info: 	Microsoft Defender Antivirus: enabled (AV)
info: 	Windows-Firewall: enabled (FW)
info: ---------------------------------
info: audio settings reset:
	samples per sec: 44100
	speakers:        2
	max buffering:   1044 milliseconds
	buffering type:  dynamically increasing
Audio reset result: true
Error on libobs reset video: -3 (Invalid Parameter)
Failed to get current video info
Exception in thread "main" java.lang.RuntimeException: Failed to reset video
	at com.osiris.sandbox.LibOBS.main(LibOBS.java:158)

Process finished with exit code 1
Show code
package com.osiris.sandbox;

import com.sun.jna.*;

import java.io.File;
import java.util.*;

public class LibOBS {
    static {
        String path = System.getProperty("jna.library.path");
        path += File.pathSeparator + "C:\\Program Files (x86)\\obs-studio\\bin\\64bit" +
                File.pathSeparator + "C:\\Program Files (x86)\\obs-studio\\obs-plugins\\64bit";
        System.setProperty("jna.library.path", path);
    }
    public interface ObsLibrary extends Library {
        ObsLibrary INSTANCE = Native.load("obs", ObsLibrary.class);

        String obs_get_version_string();
        boolean obs_initialized();
        boolean obs_startup(String locale, String module_config_path, Pointer profiler_name);
        void obs_shutdown();
        void obs_add_data_path(String path);
        void obs_add_module_path(String bin_path, String data_path);
        boolean obs_reset_audio(obs_audio_info avi);
        int obs_reset_video(obs_video_info ovi);
        void obs_load_all_modules();
        void obs_log_loaded_modules();
        void obs_post_load_modules();

        Pointer obs_source_create(String id, String name, Pointer settings, Pointer hotkey_data);
        void obs_set_output_source(int channel, Pointer source);
        Pointer obs_data_create();
        void obs_data_set_bool(Pointer data, String name, boolean value);
        void obs_data_set_string(Pointer data, String name, String value);
        void obs_data_set_int(Pointer data, String name, long value);
        Pointer obs_video_encoder_create(String id, String name, Pointer settings, Pointer hotkey_data);
        void obs_encoder_set_video(Pointer encoder, Pointer video);
        void obs_data_release(Pointer data);
        Pointer obs_audio_encoder_create(String id, String name, Pointer settings, long track, Pointer hotkey_data);
        void obs_encoder_set_audio(Pointer encoder, Pointer audio);
        Pointer obs_output_create(String id, String name, Pointer settings, Pointer hotkey_data);
        void obs_output_set_video_encoder(Pointer output, Pointer encoder);
        void obs_output_set_audio_encoder(Pointer output, Pointer encoder, long track);
        boolean obs_output_start(Pointer output);
        String obs_output_get_last_error(Pointer output);
        Pointer obs_output_get_proc_handler(Pointer output);
        String obs_output_get_id(Pointer output);
        Pointer obs_get_video();
        int obs_get_video_info(obs_video_info ovi);
    }

    public static class VideoResetError {
        public static final int OBS_VIDEO_SUCCESS = 0;
        public static final int OBS_VIDEO_FAIL = -1;
        public static final int OBS_VIDEO_NOT_SUPPORTED = -2;
        public static final int OBS_VIDEO_INVALID_PARAM = -3;
        public static final int OBS_VIDEO_CURRENTLY_ACTIVE = -4;
        public static final int OBS_VIDEO_MODULE_NOT_FOUND = -5;

        public static String getErrorString(int error) {
            switch (error) {
                case OBS_VIDEO_SUCCESS: return "Success";
                case OBS_VIDEO_FAIL: return "Fail";
                case OBS_VIDEO_NOT_SUPPORTED: return "Not Supported";
                case OBS_VIDEO_INVALID_PARAM: return "Invalid Parameter";
                case OBS_VIDEO_CURRENTLY_ACTIVE: return "Video Currently Active";
                case OBS_VIDEO_MODULE_NOT_FOUND: return "Module Not Found";
                default: return "Unknown Error";
            }
        }
    }

    public static class obs_audio_info extends Structure {
        public int samples_per_sec;
        public int speakers;

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("samples_per_sec", "speakers");
        }
    }

    public static class obs_video_info extends Structure {
        public int adapter;
        public String graphics_module;
        public int fps_num;
        public int fps_den;
        public int base_width;
        public int base_height;
        public int output_width;
        public int output_height;
        public int output_format;
        public boolean gpu_conversion;
        public int colorspace;
        public int range;
        public int scale_type;

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("adapter", "graphics_module", "fps_num", "fps_den", "base_width", "base_height",
                    "output_width", "output_height", "output_format", "gpu_conversion", "colorspace", "range", "scale_type");
        }
    }

    public static void main(String[] args) {
        ObsLibrary obs = ObsLibrary.INSTANCE;

        System.out.println("libobs version: " + obs.obs_get_version_string());

        if (!obs.obs_startup("en-US", null, null)) {
            throw new RuntimeException("error on libobs startup");
        }

        //obs.obs_add_data_path("./data/libobs/");
        //obs.obs_add_module_path("./obs-plugins/64bit/", "./data/obs-plugins/%module%/");

        obs_audio_info avi = new obs_audio_info();
        avi.samples_per_sec = 44100;
        avi.speakers = 2; // Assuming SPEAKERS_STEREO is 2

        boolean resetAudioCode = obs.obs_reset_audio(avi);
        System.out.println("Audio reset result: " + resetAudioCode);

        int mainWidth = 1280;  // Reduced from 1920
        int mainHeight = 720;  // Reduced from 1080

        obs_video_info ovi = new obs_video_info();
        ovi.adapter = 0;
        ovi.graphics_module = "libobs-opengl"; // Assuming Linux environment
        ovi.fps_num = 60;
        ovi.fps_den = 1;
        ovi.base_width = mainWidth;
        ovi.base_height = mainHeight;
        ovi.output_width = mainWidth;
        ovi.output_height = mainHeight;
        ovi.output_format = 1; // Changed from 0 to 1 (NV12 to I420)
        ovi.gpu_conversion = true;
        ovi.colorspace = 0; // Assuming VIDEO_CS_DEFAULT is 0
        ovi.range = 0; // Assuming VIDEO_RANGE_DEFAULT is 0
        ovi.scale_type = 0; // Assuming OBS_SCALE_BILINEAR is 0

        int resetVideoCode = obs.obs_reset_video(ovi);
        if (resetVideoCode != 0) {
            System.err.println("Error on libobs reset video: " + resetVideoCode + " (" + VideoResetError.getErrorString(resetVideoCode) + ")");

            // Try to get current video info
            obs_video_info currentOvi = new obs_video_info();
            int getVideoInfoResult = obs.obs_get_video_info(currentOvi);
            if (getVideoInfoResult == 0) {
                System.out.println("Current video settings:");
                System.out.println("Base resolution: " + currentOvi.base_width + "x" + currentOvi.base_height);
                System.out.println("Output resolution: " + currentOvi.output_width + "x" + currentOvi.output_height);
                System.out.println("FPS: " + currentOvi.fps_num + "/" + currentOvi.fps_den);
            } else {
                System.err.println("Failed to get current video info");
            }

            throw new RuntimeException("Failed to reset video");
        }

        System.out.println("Video reset successful");

        obs.obs_load_all_modules();
        obs.obs_log_loaded_modules();
        obs.obs_post_load_modules();

        // The rest of the code (setting up sources, encoders, outputs) would follow here...

        System.out.println("Press Enter to exit...");
        Scanner scanner = new Scanner(System.in);
        scanner.nextLine();

        // Don't forget to shut down OBS
        obs.obs_shutdown();
    }
}
@Osiris-Team Osiris-Team changed the title Error on libobs reset video: -3 (Invalid Parameter) Error on libobs reset video: -5 (Module Not Found) Jul 11, 2024
@Osiris-Team Osiris-Team changed the title Error on libobs reset video: -5 (Module Not Found) Error on libobs reset video: -3 (Invalid Parameter) Jul 11, 2024
@lulzsun
Copy link
Owner

lulzsun commented Jul 15, 2024

Hi, I've taken a look at your code and it seems like everything should work fine, so I am not sure what the issue may be.

My guess would be that there is an issue creating the obs_video_info object. I am not familiar with Java or the JNA library that you are using, but I'm guessing it may be related to JNA not correctly handling the initialization of the object.

https://github.com/obsproject/obs-studio/blob/1cb1864cc04e1036ea4066ee862f6ac88ea708d5/libobs/media-io/video-io.c#L226

static inline bool valid_video_params(const struct video_output_info *info)
{
	return info->height != 0 && info->width != 0 && info->fps_den != 0 &&
	       info->fps_num != 0;
}

From what I can tell, it looks like you are initializing the object correctly; output_height, output_width, fps_den, and fps_num should be non-zero values. Could you maybe try to print out the properties of the object before calling obs_reset_video to double check if its valid?

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