void EngineController::endSession() { //only update song stats, when we're not going to resume it if ( !AmarokConfig::resumePlayback() && m_currentTrack ) { playbackEnded( trackPosition(), m_currentTrack->length(), EngineObserver::EndedQuit ); emit trackChanged( Meta::TrackPtr( 0 ) ); } }
void PlayerComponent::handleMpvEvent(mpv_event *event) { switch (event->event_id) { case MPV_EVENT_START_FILE: { m_CurrentUrl = mpv::qt::get_property_variant(m_mpv, "path").toString(); m_playbackStartSent = false; break; } case MPV_EVENT_FILE_LOADED: { emit playing(m_CurrentUrl); break; } case MPV_EVENT_END_FILE: { mpv_event_end_file *end_file = (mpv_event_end_file *)event->data; switch (end_file->reason) { case MPV_END_FILE_REASON_EOF: emit finished(m_CurrentUrl); break; case MPV_END_FILE_REASON_ERROR: emit error(end_file->error, mpv_error_string(end_file->error)); break; default: emit stopped(m_CurrentUrl); break; } emit playbackEnded(m_CurrentUrl); m_CurrentUrl = ""; m_restoreDisplayTimer.start(0); break; } case MPV_EVENT_IDLE: { emit playbackAllDone(); break; } case MPV_EVENT_PLAYBACK_RESTART: { // it's also sent after seeks are completed if (!m_playbackStartSent) emit playbackStarting(); m_playbackStartSent = true; break; } case MPV_EVENT_PROPERTY_CHANGE: { mpv_event_property *prop = (mpv_event_property *)event->data; if (strcmp(prop->name, "pause") == 0 && prop->format == MPV_FORMAT_FLAG) { int state = *(int *)prop->data; emit paused(state); } else if (strcmp(prop->name, "cache-buffering-state") == 0 && prop->format == MPV_FORMAT_INT64) { int64_t percentage = *(int64_t *)prop->data; emit buffering(percentage); } else if (strcmp(prop->name, "playback-time") == 0 && prop->format == MPV_FORMAT_DOUBLE) { double pos = *(double*)prop->data; if (fabs(pos - m_lastPositionUpdate) > 0.25) { quint64 ms = (quint64)(qMax(pos * 1000.0, 0.0)); emit positionUpdate(ms); m_lastPositionUpdate = pos; } } else if (strcmp(prop->name, "vo-configured") == 0) { int state = prop->format == MPV_FORMAT_FLAG ? *(int *)prop->data : 0; emit windowVisible(state); } else if (strcmp(prop->name, "duration") == 0) { if (prop->format == MPV_FORMAT_DOUBLE) emit updateDuration(*(double *)prop->data * 1000.0); } else if (strcmp(prop->name, "audio-device-list") == 0) { updateAudioDeviceList(); } break; } case MPV_EVENT_LOG_MESSAGE: { mpv_event_log_message *msg = (mpv_event_log_message *)event->data; // Strip the trailing '\n' size_t len = strlen(msg->text); if (len > 0 && msg->text[len - 1] == '\n') len -= 1; QString logline = QString::fromUtf8(msg->prefix) + ": " + QString::fromUtf8(msg->text, len); if (msg->log_level >= MPV_LOG_LEVEL_V) QLOG_DEBUG() << qPrintable(logline); else if (msg->log_level >= MPV_LOG_LEVEL_INFO) QLOG_INFO() << qPrintable(logline); else if (msg->log_level >= MPV_LOG_LEVEL_WARN) QLOG_WARN() << qPrintable(logline); else QLOG_ERROR() << qPrintable(logline); break; } case MPV_EVENT_CLIENT_MESSAGE: { mpv_event_client_message *msg = (mpv_event_client_message *)event->data; // This happens when the player is about to load the file, but no actual loading has taken part yet. // We use this to block loading until we explicitly tell it to continue. if (msg->num_args >= 3 && !strcmp(msg->args[0], "hook_run") && !strcmp(msg->args[1], "1")) { QString resume_id = QString::fromUtf8(msg->args[2]); // Calling this lambda will instruct mpv to continue loading the file. auto resume = [=] { QLOG_INFO() << "resuming loading"; mpv::qt::command_variant(m_mpv, QStringList() << "hook-ack" << resume_id); }; if (switchDisplayFrameRate()) { // Now wait for some time for mode change - this is needed because mode changing can take some // time, during which the screen is black, and initializing hardware decoding could fail due // to various strange OS-related reasons. // (Better hope the user doesn't try to exit Konvergo during mode change.) int pause = SettingsComponent::Get().value(SETTINGS_SECTION_VIDEO, "refreshrate.delay").toInt() * 1000; QLOG_INFO() << "waiting" << pause << "msec after rate switch before loading"; QTimer::singleShot(pause, resume); } else { resume(); } break; } } default:; /* ignore */ } }
int main() { // Objects CameraInput *camera = new CameraInput(); Control *controller = new Control(); Process *processer = new Process(); Tracking *tracker = new Tracking(); Serial_Communication *serial = new Serial_Communication("/dev/ttyUSB0", "/dev/ttyUSB1"); // Serial_Communication *serial = new Serial_Communication("/dev/ttyUSB0");// #### For testing with only one arduino File_Handler *file_Handler = new File_Handler(); Window_Handler *window_Handler = new Window_Handler(); Menu *menu = new Menu(); // Threads QThread *t1 = new QThread; QThread *t2 = new QThread; QThread *t3 = new QThread; QThread *t4 = new QThread; QThread *t5 = new QThread; camera->moveToThread(t1); processer->moveToThread(t2); tracker->moveToThread(t3); serial->moveToThread(t3); controller->moveToThread(t4); file_Handler->moveToThread(t5); // Connect signals to slots. Whenever a signal is emitted in a function, its corresponding (connected) function will run. qRegisterMetaType<cv::Mat>("cv::Mat"); //Signals calling from: //Main thread QObject::connect(menu, SIGNAL(startRecording(bool)), controller, SLOT(startRecording(bool))); QObject::connect(menu, SIGNAL(stopRecording()), controller, SLOT(stopRecording())); QObject::connect(menu, SIGNAL(displayMenu(cv::Mat)), window_Handler, SLOT(drawImage(cv::Mat))); QObject::connect(menu, SIGNAL(requestDataFromFootController()), serial, SLOT(receiveDataFromFootControllerLoop())); QObject::connect(menu, SIGNAL(startHighRep()), controller, SLOT(startDelayMode())); QObject::connect(menu, SIGNAL(decreaseDelay()), controller, SLOT(decreaseDelay())); QObject::connect(menu, SIGNAL(increaseDelay()), controller, SLOT(increaseDelay())); QObject::connect(menu, SIGNAL(modeSwitch()), controller, SLOT(endMode())); QObject::connect(menu, SIGNAL(startPlayback()), file_Handler, SLOT(readFromFile())); QObject::connect(menu, SIGNAL(stopPlayback()), file_Handler, SLOT(stopVideo())); QObject::connect(menu, SIGNAL(toggleSlowMotion()), file_Handler, SLOT(toggleSlowMotion())); QObject::connect(menu, SIGNAL(toggleTracking()), controller, SLOT(toggleTracking())); //Thread 1 QObject::connect(t1, SIGNAL(started()), camera, SLOT(captureImage())); QObject::connect(camera, SIGNAL(capturedImage(cv::Mat)), controller, SLOT(inputImage(cv::Mat))); //Thread 2 QObject::connect(t2, SIGNAL(started()), controller, SLOT(processerReady())); QObject::connect(processer, SIGNAL(posXposY(int,int)), tracker, SLOT(position(int,int))); QObject::connect(processer, SIGNAL(readyForWork()), controller, SLOT(processerReady())); //Thread 3 QObject::connect(tracker, SIGNAL(directionAndSpeed(int,int)), serial, SLOT(sendDataToControlUnit(int,int))); QObject::connect(serial, SIGNAL(fromFootController(char)), menu, SLOT(giveInput(char))); //Thread 4 QObject::connect(t4, SIGNAL(started()), controller, SLOT(fileHandlerReadyToWrite())); QObject::connect(controller, SIGNAL(imageToProcess(cv::Mat)), processer, SLOT(processImage(cv::Mat))); QObject::connect(controller, SIGNAL(requestImage()), camera, SLOT(captureImage())); QObject::connect(controller, SIGNAL(imageToRecord(cv::Mat)), file_Handler, SLOT(writeImage(cv::Mat))); // QObject::connect(controller, SIGNAL(imageToShow(cv::Mat)), window_Handler, SLOT(drawImage(cv::Mat))); QObject::connect(processer, SIGNAL(processedImage(cv::Mat)), window_Handler, SLOT(drawImage(cv::Mat))); QObject::connect(controller, SIGNAL(stopMotor()), serial, SLOT(stopMotor())); //Thread 5 QObject::connect(file_Handler, SIGNAL(showFrame(cv::Mat)), window_Handler, SLOT(drawImage(cv::Mat))); QObject::connect(file_Handler, SIGNAL(readyToWrite()), controller, SLOT(fileHandlerReadyToWrite())); QObject::connect(file_Handler, SIGNAL(timeout()), file_Handler, SLOT(playVideo())); QObject::connect(file_Handler, SIGNAL(playbackEnded()), menu, SLOT(returnToLowRep())); // Starting Threads t1->start(); t2->start(); t3->start(); t4->start(); t5->start(); // menu->menu(); menu->inputHandler(); return 0; }