Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SerialPrograms/Source/CommonFramework/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace PokemonAutomation{
const bool IS_BETA_VERSION = true;
const int PROGRAM_VERSION_MAJOR = 0;
const int PROGRAM_VERSION_MINOR = 55;
const int PROGRAM_VERSION_PATCH = 1;
const int PROGRAM_VERSION_PATCH = 2;

const std::string PROGRAM_VERSION_BASE =
"v" + std::to_string(PROGRAM_VERSION_MAJOR) +
Expand Down
257 changes: 178 additions & 79 deletions SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,109 +90,208 @@ void VideoSession::set(const VideoSourceOption& option){
}

void VideoSession::reset(){
m_logger.log("Resetting the video...", COLOR_GREEN);
dispatch_to_main_thread([this]{
std::lock_guard<std::mutex> lg0(m_reset_lock);
{
WriteSpinLock lg(m_queue_lock);
// cout << "VideoSession::reset(): " << m_queued_commands.size() << endl;
m_queued_commands.emplace_back(
Command{
CommandType::RESET,
nullptr,
Resolution{}
}
);
}
dispatch_to_main_thread([this]{ run_commands(); });
}
void VideoSession::set_source(
const std::shared_ptr<VideoSourceDescriptor>& device,
Resolution resolution
){
{
WriteSpinLock lg(m_queue_lock);
// cout << "VideoSession::set_source(): " << m_queued_commands.size() << endl;
m_queued_commands.emplace_back(
Command{
CommandType::SET_SOURCE,
device,
resolution
}
);
}
dispatch_to_main_thread([this]{ run_commands(); });
}
void VideoSession::set_resolution(Resolution resolution){
{
WriteSpinLock lg(m_queue_lock);
// cout << "VideoSession::set_resolution(): " << m_queued_commands.size() << endl;
m_queued_commands.emplace_back(
Command{
CommandType::SET_RESOLUTION,
nullptr,
resolution
}
);
}
dispatch_to_main_thread([this]{ run_commands(); });
}

m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
void VideoSession::internal_reset(){
m_logger.log("Resetting the video...", COLOR_GREEN);
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);

{
WriteSpinLock lg(m_state_lock);
if (m_video_source){
m_video_source->remove_source_frame_listener(*this);
m_video_source->remove_rendered_frame_listener(*this);
m_video_source.reset();
}
Resolution resolution = m_option.m_resolution;
std::unique_ptr<VideoSource> source;
{
WriteSpinLock lg(m_state_lock);
source = std::move(m_video_source);
}
if (source){
source->remove_source_frame_listener(*this);
source->remove_rendered_frame_listener(*this);
source.reset();
}

m_video_source = m_descriptor->make_VideoSource(m_logger, m_option.m_resolution);
source = m_descriptor->make_VideoSource(m_logger, resolution);
if (source){
resolution = source->current_resolution();
source->add_source_frame_listener(*this);
source->add_rendered_frame_listener(*this);
}

if (m_video_source){
m_option.m_resolution = m_video_source->current_resolution();
m_video_source->add_source_frame_listener(*this);
m_video_source->add_rendered_frame_listener(*this);
}
}
{
WriteSpinLock lg(m_state_lock);
m_option.m_resolution = resolution;
m_video_source = std::move(source);
}

m_state_listeners.run_method_unique(
&StateListener::post_startup,
m_video_source.get()
);
});
m_state_listeners.run_method_unique(
&StateListener::post_startup,
m_video_source.get()
);
}
void VideoSession::set_source(
void VideoSession::internal_set_source(
const std::shared_ptr<VideoSourceDescriptor>& device,
Resolution resolution
){
m_logger.log("Changing video...", COLOR_GREEN);
dispatch_to_main_thread([this, device, resolution]{
std::lock_guard<std::mutex> lg0(m_reset_lock);
if (*m_descriptor == *device && !m_descriptor->should_reload()){
return;
}

m_state_listeners.run_method_unique(&StateListener::pre_shutdown);

{
WriteSpinLock lg(m_state_lock);
if (m_video_source){
m_video_source->remove_source_frame_listener(*this);
m_video_source->remove_rendered_frame_listener(*this);
m_video_source.reset();
}
if (*m_descriptor == *device && !m_descriptor->should_reload()){
return;
}

m_option.set_descriptor(device);
m_descriptor = device;
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);

Resolution desired_resolution = resolution ? resolution : m_option.m_resolution;
// cout << "VideoSession::set_source(): " << &m_option << " - " << desired_resolution.width << " x " << desired_resolution.height << endl;
std::unique_ptr<VideoSource> source;
{
WriteSpinLock lg(m_state_lock);
source = std::move(m_video_source);
}
if (source){
source->remove_source_frame_listener(*this);
source->remove_rendered_frame_listener(*this);
source.reset();
}
{
WriteSpinLock lg(m_state_lock);
m_option.set_descriptor(device);
m_descriptor = device;
}

m_video_source = device->make_VideoSource(m_logger, desired_resolution);
Resolution desired_resolution = resolution ? resolution : m_option.m_resolution;
source = device->make_VideoSource(m_logger, desired_resolution);
if (source){
resolution = source->current_resolution();
source->add_source_frame_listener(*this);
source->add_rendered_frame_listener(*this);
}

if (m_video_source){
m_option.m_resolution = m_video_source->current_resolution();
m_video_source->add_source_frame_listener(*this);
m_video_source->add_rendered_frame_listener(*this);
}
}
{
WriteSpinLock lg(m_state_lock);
m_option.m_resolution = resolution;
m_video_source = std::move(source);
}

m_state_listeners.run_method_unique(
&StateListener::post_startup,
m_video_source.get()
);
});
m_state_listeners.run_method_unique(
&StateListener::post_startup,
m_video_source.get()
);
}
void VideoSession::set_resolution(Resolution resolution){
void VideoSession::internal_set_resolution(Resolution resolution){
m_logger.log("Changing resolution...", COLOR_GREEN);
dispatch_to_main_thread([this, resolution]{
std::lock_guard<std::mutex> lg0(m_reset_lock);
if (m_option.m_resolution == resolution){
return;
}
if (m_option.m_resolution == resolution){
return;
}

m_state_listeners.run_method_unique(&StateListener::pre_shutdown);

std::unique_ptr<VideoSource> source;
{
WriteSpinLock lg(m_state_lock);
source = std::move(m_video_source);
}
if (source){
source->remove_source_frame_listener(*this);
source->remove_rendered_frame_listener(*this);
source.reset();
}

source = m_descriptor->make_VideoSource(m_logger, resolution);
if (source){
resolution = source->current_resolution();
source->add_source_frame_listener(*this);
source->add_rendered_frame_listener(*this);
}

{
WriteSpinLock lg(m_state_lock);
m_option.m_resolution = resolution;
m_video_source = std::move(source);
}

{
WriteSpinLock lg(m_state_lock);
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
m_state_listeners.run_method_unique(
&StateListener::post_startup,
m_video_source.get()
);
}

if (m_video_source){
m_video_source->remove_source_frame_listener(*this);
m_video_source->remove_rendered_frame_listener(*this);
m_video_source.reset();
void VideoSession::run_commands(){
std::lock_guard<std::recursive_mutex> lg0(m_reset_lock);
if (m_recursion_depth != 0){
m_logger.log("Suppressing re-entrant command...", COLOR_RED);
return;
}
m_recursion_depth++;
try{
while (true){
Command command;
{
WriteSpinLock lg(m_queue_lock);
// cout << "VideoSession::run_commands(): " << m_queued_commands.size() << endl;
if (m_queued_commands.empty()){
break;
}
command = std::move(m_queued_commands.front());
m_queued_commands.pop_front();
}

m_video_source = m_descriptor->make_VideoSource(m_logger, resolution);
switch (command.command_type){
case CommandType::RESET:
internal_reset();
break;

if (m_video_source){
m_option.m_resolution = m_video_source->current_resolution();
m_video_source->add_source_frame_listener(*this);
m_video_source->add_rendered_frame_listener(*this);
case CommandType::SET_SOURCE:
internal_set_source(command.device, command.resolution);
break;

case CommandType::SET_RESOLUTION:
internal_set_resolution(command.resolution);
break;
}
}

m_state_listeners.run_method_unique(
&StateListener::post_startup,
m_video_source.get()
);
});
m_recursion_depth--;
}catch (...){
m_recursion_depth--;
throw;
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define PokemonAutomation_VideoPipeline_VideoSession_H

#include <memory>
#include <deque>
#include <mutex>
#include "Common/Cpp/EventRateTracker.h"
#include "Common/Cpp/Concurrency/SpinLock.h"
Expand Down Expand Up @@ -176,7 +177,28 @@ class VideoSession


private:
mutable std::mutex m_reset_lock;
enum CommandType{
RESET,
SET_SOURCE,
SET_RESOLUTION
};
struct Command{
CommandType command_type;
std::shared_ptr<VideoSourceDescriptor> device;
Resolution resolution;
};
void run_commands();

void internal_reset();
void internal_set_source(
const std::shared_ptr<VideoSourceDescriptor>& device,
Resolution resolution = {}
);
void internal_set_resolution(Resolution resolution);


private:
mutable std::recursive_mutex m_reset_lock;
mutable SpinLock m_state_lock;

Logger& m_logger;
Expand All @@ -189,6 +211,12 @@ class VideoSession
std::shared_ptr<const VideoSourceDescriptor> m_descriptor;
std::unique_ptr<VideoSource> m_video_source;

// We need to queue up all reset commands and run them on the main thread.
// This is needed to prevent re-entrant calls from event processing.
SpinLock m_queue_lock;
size_t m_recursion_depth = 0;
std::deque<Command> m_queued_commands;

ListenerSet<StateListener> m_state_listeners;
ListenerSet<VideoFrameListener> m_frame_listeners;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@
#include "PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_PathSide.h"
#include "PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_PathMap.h"
#include "NintendoSwitch/Inference/NintendoSwitch_SelectedSettingDetector.h"
#include "PokemonSV/Inference/Boxes/PokemonSV_BoxShinyDetector.h"
#include "PokemonSwSh/Inference/PokemonSwSh_DialogBoxDetector.h"

#include <QPixmap>
#include <QVideoFrame>
Expand Down Expand Up @@ -260,10 +262,23 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope&

auto screenshot = feed.snapshot();

YCommIconDetector detector(true);
PokemonSwSh::BlackDialogBoxDetector detector(true);
detector.make_overlays(overlays);
cout << detector.process_frame(screenshot, current_time()) << endl;



// PokemonSV::BoxShinyDetector detector;
// cout << detector.detect(screenshot) << endl;




#if 0
YCommIconDetector detector(true);
cout << detector.process_frame(screenshot, current_time()) << endl;
#endif

#if 0
bool switch2 = true;
ImageFloatBox key1_box;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,6 @@ ConsoleSettingsPanel::ConsoleSettingsPanel(const ConsoleSettings_Descriptor& des
, settings(ConsoleSettings::instance())
{
PA_ADD_OPTION(settings);

settings.CONTROLLER_SETTINGS.set_visibility(
settings.CONTROLLER_SETTINGS.current_rows() > 0
? ConfigOptionState::ENABLED
: ConfigOptionState::HIDDEN
);
}


Expand Down
Loading