int LshttpdMain::processAdminCmd( char * pCmd, char * pEnd, int &apply ) { if ( strncasecmp( pCmd, "reload:", 7 ) == 0 ) { apply = 1; pCmd += 7; if ( strncasecmp( pCmd, "config", 6 ) == 0 ) { LOG_NOTICE(( "Reload configuration request from admin interface!" )); reconfig(); } /* COMMENT: Not support reconfigVHost NOW. else if ( strncasecmp( pCmd, "vhost:", 6 ) == 0 ) { pCmd += 6; LOG_NOTICE(( "Reload configuration for virtual host %s!", pCmd )); if ( m_pBuilder->loadConfigFile( NULL ) == 0 ) m_pServer->reconfigVHost( pCmd, m_pBuilder->getRoot() ); //m_pBuilder->reconfigVHost( pCmd ); }*/ } else if ( strncasecmp( pCmd, "enable:", 7 ) == 0 ) { apply = 1; pCmd += 7; if ( strncasecmp( pCmd, "vhost:", 6 ) == 0 ) { pCmd += 6; if ( !m_pServer->enableVHost( pCmd, 1 ) ) LOG_NOTICE(( "Virtual host %s is enabled!", pCmd )); else LOG_ERR(( "Virtual host %s can not be enabled, reload first!", pCmd )); } } else if ( strncasecmp( pCmd, "disable:", 8 ) == 0 ) { apply = 1; pCmd += 8; if ( strncasecmp( pCmd, "vhost:", 6 ) == 0 ) { pCmd += 6; if ( !m_pServer->enableVHost( pCmd, 0 ) ) LOG_NOTICE(( "Virtual host %s is disabled!", pCmd )); else LOG_ERR(( "Virtual host %s can not be disabled, reload first!", pCmd )); } } else if ( strncasecmp( pCmd, "restart", 7 ) == 0 ) { LOG_NOTICE(( "Server restart request from admin interface!" )); gracefulRestart(); } else if ( strncasecmp( pCmd, "toggledbg", 7 ) == 0 ) { LOG_NOTICE(( "Toggle debug logging request from admin interface!" )); broadcastSig( SIGUSR2, 0 ); apply = 0; } return 0; }
CodeEditor::CodeEditor(Config* config, QWidget* parent) : QPlainTextEdit(parent), config(config) { highlighter = new Highlighter(config, this); // тормоз extraArea = new QWidget(this); extraArea->setCursor(Qt::PointingHandCursor); extraArea->setAutoFillBackground(true); extraArea->installEventFilter(this); completer = new QCompleter(config->keywordsSorted, this); completer->setWidget(this); completer->setCompletionMode(QCompleter::PopupCompletion); completer->setWrapAround(false); setLineWrapMode(QPlainTextEdit::NoWrap); setCursorWidth(2); blockCountChanged(0); setMouseTracking(true); reconfig(); // не допускаем проваливание на последнем свернутом блоке connect(this, SIGNAL(cursorPositionChanged()), SLOT(ensureCursorVisible())); connect(this, SIGNAL(blockCountChanged(int)), SLOT(blockCountChanged(int))); connect(document(), SIGNAL(contentsChange(int, int, int)), SLOT(contentsChange(int, int, int))); connect(completer, SIGNAL(activated(const QString&)), SLOT(insertCompletion(const QString&))); connect(config, SIGNAL(reread(int)), SLOT(reconfig(int))); connect(this, SIGNAL(updateRequest(QRect, int)), extraArea, SLOT(update())); }
void IpVerify::refreshDNS() { // NOTE: this may be called when the daemon is starting a reconfig. // The new configuration may not have been read yet, but we do // not care, because this just sets a flag and we do the actual // work later. reconfig(); }
void UpdateConfiguration() { extern Boolean init_dvi_file(void); extern void ReopenDviFile(void); initcolor(); /* FIXME : this should happen only if mode or bdpi changed or shrink factor has changed. */ reset_fonts(); reconfig(); SendMessage(hWndDraw, WM_ERASEBKGND, (WPARAM)GetDC(hWndDraw), 0); ChangePage(0); }
LRESULT CmdViewConfigOK(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl) { /* Retrieve the values in the dialog and set them as current */ /* EndDialog(hdlg, TRUE); /* Exit the dialog */ #if PS ps_destroy(); #endif initcolor(); reconfig(); redraw_page(); return 0; }
/* _signal_handler - Process daemon-wide signals */ static void *_signal_handler(void *no_data) { int rc, sig; int sig_array[] = {SIGINT, SIGTERM, SIGHUP, SIGABRT, SIGUSR2, 0}; sigset_t set; (void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); /* Make sure no required signals are ignored (possibly inherited) */ _default_sigaction(SIGINT); _default_sigaction(SIGTERM); _default_sigaction(SIGHUP); _default_sigaction(SIGABRT); _default_sigaction(SIGUSR2); while (1) { xsignal_sigset_create(sig_array, &set); rc = sigwait(&set, &sig); if (rc == EINTR) continue; switch (sig) { case SIGHUP: /* kill -1 */ info("Reconfigure signal (SIGHUP) received"); reconfig(); break; case SIGINT: /* kill -2 or <CTRL-C> */ case SIGTERM: /* kill -15 */ info("Terminate signal (SIGINT or SIGTERM) received"); shutdown_threads(); return NULL; /* Normal termination */ case SIGABRT: /* abort */ info("SIGABRT received"); abort(); /* Should terminate here */ shutdown_threads(); return NULL; case SIGUSR2: info("Logrotate signal (SIGUSR2) received"); _update_logging(false); break; default: error("Invalid signal (%d) received", sig); } } }
void HiwrCameraControllerNodelet::spin() { NODELET_INFO("[UVC Cam Nodelet] Main Loop..."); printf("inside spinOnce loop \n"); dynamic_reconfigure::Server<Config> srv; dynamic_reconfigure::Server<Config>::CallbackType f = boost::bind(&HiwrCameraControllerNodelet::reconfig, this, _1, _2); srv.setCallback(f); reconfig(config_, 0xffffffff); applyNewConfig(config_ , 0xffffffff); spinning_thread_ = boost::shared_ptr< boost::thread > (new boost::thread(boost::bind(&HiwrCameraControllerNodelet::loopGrabImage, this))); while (ros::ok()) { if (state_ != Driver::CLOSED) { //Check nb subscribers if(image_pub_.getNumSubscribers() > 0 && !next_config_update_) { if (spining_state_ == true && next_config_count_ > 0 && read() ) { cv_bridge::CvImagePtr cv_ptr(new cv_bridge::CvImage); cv_ptr->header.stamp = ros::Time::now(); cv_ptr->header.frame_id = config_.frame_id; cv_ptr->encoding = sensor_msgs::image_encodings::MONO8; //"mono8";//"bgr8"; cv_ptr->image = Mat( image_ipl_ ); image_pub_.publish(cv_ptr->toImageMsg()); }else{ usleep(1000);//1ms sleep } }else{ usleep(1000); } } ros::spinOnce(); } }
void DCCollector::init( bool needs_reconfig ) { static long bootTime = 0; update_rsock = NULL; use_tcp = true; use_nonblocking_update = true; update_destination = NULL; if (bootTime == 0) { bootTime = time( NULL ); } startTime = bootTime; if( needs_reconfig ) { reconfig(); } }
bool StarterHookMgr::initialize(ClassAd* job_ad) { char* tmp = param("STARTER_JOB_HOOK_KEYWORD"); if (tmp) { m_hook_keyword = tmp; dprintf(D_FULLDEBUG, "Using STARTER_JOB_HOOK_KEYWORD value from config file: \"%s\"\n", m_hook_keyword); } else if (!job_ad->LookupString(ATTR_HOOK_KEYWORD, &m_hook_keyword)) { dprintf(D_FULLDEBUG, "Job does not define %s, not invoking any job hooks.\n", ATTR_HOOK_KEYWORD); return true; } else { dprintf(D_FULLDEBUG, "Using %s value from job ClassAd: \"%s\"\n", ATTR_HOOK_KEYWORD, m_hook_keyword); } if (!reconfig()) return false; return HookClientMgr::initialize(); }
bool JobRouterHookMgr::initialize() { reconfig(); return HookClientMgr::initialize(); }
int main(int argc, char *argv[]) { enum { CACHE_SHARED, CACHE_SET, CACHE_NONE } cache; TEST_OPTS *opts, _opts; WT_RAND_STATE rnd; WT_SESSION *session; size_t len; u_int i, j; const char *p; char *config; opts = &_opts; memset(opts, 0, sizeof(*opts)); opts->table_type = TABLE_ROW; testutil_check(testutil_parse_opts(argc, argv, opts)); testutil_make_work_dir(opts->home); testutil_check( wiredtiger_open(opts->home, &event_handler, "create", &opts->conn)); /* Open an LSM file so the LSM reconfiguration options make sense. */ testutil_check( opts->conn->open_session(opts->conn, NULL, NULL, &session)); testutil_check(session->create( session, opts->uri, "type=lsm,key_format=S,value_format=S")); /* Initialize the RNG. */ __wt_random_init_seed(NULL, &rnd); /* Allocate memory for the config. */ len = WT_ELEMENTS(list) * 64; config = dmalloc(len); /* Set an alarm so we can debug hangs. */ (void)signal(SIGALRM, on_alarm); /* A linear pass through the list. */ for (i = 0; i < WT_ELEMENTS(list); ++i) reconfig(opts, session, list[i]); /* * A linear pass through the list, adding random elements. * * WiredTiger configurations are usually "the last one set wins", but * "shared_cache" and "cache_set" options aren't allowed in the same * configuration string. */ for (i = 0; i < WT_ELEMENTS(list); ++i) { p = list[i]; cache = CACHE_NONE; if (WT_PREFIX_MATCH(p, ",shared_cache")) cache = CACHE_SHARED; else if (WT_PREFIX_MATCH(p, ",cache_size")) cache = CACHE_SET; strcpy(config, p); for (j = (__wt_random(&rnd) % WT_ELEMENTS(list)) + 1; j > 0; --j) { p = list[__wt_random(&rnd) % WT_ELEMENTS(list)]; if (WT_PREFIX_MATCH(p, ",shared_cache")) { if (cache == CACHE_SET) continue; cache = CACHE_SHARED; } else if (WT_PREFIX_MATCH(p, ",cache_size")) { if (cache == CACHE_SHARED) continue; cache = CACHE_SET; } strcat(config, p); } reconfig(opts, session, config); } /* * Turn on-close statistics off, if on-close is on and statistics were * randomly turned off during the run, close would fail. */ testutil_check(opts->conn->reconfigure( opts->conn, "statistics_log=(on_close=0)")); free(config); testutil_cleanup(opts); return (EXIT_SUCCESS); }
int SimpleFixedNodeBranch::resetRun(xmlNodePtr cur) { //estimator is always reset MyEstimator->reset(); MyEstimator->setCollectionMode(true); bitset<B_MODE_MAX> bmode(BranchMode); IParamType iparam_old(iParam); VParamType vparam_old(vParam); myNode=cur; //store old target int nw_target=iParam[B_TARGETWALKERS]; m_param.put(cur); int target_min=-1; ParameterSet p; p.add(target_min,"minimumtargetwalkers","int"); //p.add(target_min,"minimumTargetWalkers","int"); p.add(target_min,"minimumsamples","int"); //p.add(target_min,"minimumSamples","int"); p.put(cur); if (iParam[B_TARGETWALKERS] < target_min) { iParam[B_TARGETWALKERS] = target_min; } bool same_wc=true; if(BranchMode[B_DMC] && WalkerController) { string reconfig("no"); if(WalkerController->MyMethod) reconfig="yes"; string reconfig_prev(reconfig); ParameterSet p; p.add(reconfig,"reconfiguration","string"); p.put(cur); same_wc=(reconfig==reconfig_prev); } //everything is the same, do nothing if(same_wc && bmode==BranchMode && std::equal(iParam.begin(),iParam.end(),iparam_old.begin()) && std::equal(vParam.begin(),vParam.end(),vparam_old.begin()) ) { app_log() << " Continue with the same input as the previous block." << endl; app_log().flush(); return 1; } app_log() << " SimpleFixedNodeBranch::resetRun detected changes in <parameter>'s " << endl; app_log() << " BranchMode : " << bmode << " " << BranchMode << endl; //vmc does not need to do anything with WalkerController if(!BranchMode[B_DMC]) { app_log() << " iParam (old): " <<iparam_old << endl; app_log() << " iParam (new): " <<iParam << endl; app_log() << " vParam (old): " <<vparam_old << endl; app_log() << " vParam (new): " <<vParam << endl; app_log().flush(); return 1; } if(WalkerController==0) { APP_ABORT("SimpleFixedNodeBranch::resetRun cannot initialize WalkerController"); } if(!same_wc) { app_log() << "Destroy WalkerController. Existing method " << WalkerController->MyMethod << endl;; delete WalkerController; WalkerController = createWalkerController(iParam[B_TARGETWALKERS], MyEstimator->getCommunicator(), myNode); app_log().flush(); BranchMode[B_POPCONTROL]= (WalkerController->MyMethod == 0); if(BranchMode[B_POPCONTROL]) { vParam[B_ETRIAL]=vParam[B_EREF]; vParam[B_FEEDBACK]=1.0; } } //always add a warmup step using default 10 steps R2Accepted.clear(); R2Proposed.clear(); //R2Accepted(1.0e-12); //R2Proposed(1.0e-12); BranchMode[B_DMCSTAGE]=0; ToDoSteps=iParam[B_WARMUPSTEPS]=(iParam[B_WARMUPSTEPS])?iParam[B_WARMUPSTEPS]:10; BranchMode.set(B_USETAUEFF,sParam[USETAUOPT]=="no"); if(BranchMode[B_POPCONTROL]) logN = std::log(static_cast<RealType>(iParam[B_TARGETWALKERS])); else { //vParam[B_ETRIAL]=0.0; vParam[B_ETRIAL]=vParam[B_EREF]; vParam[B_FEEDBACK]=0.0; logN=0.0; } WalkerController->put(myNode); WalkerController->setEnergyAndVariance(vParam[B_EREF],vParam[B_SIGMA]); WalkerController->reset(); if(BackupWalkerController) BackupWalkerController->reset(); iParam[B_MAXWALKERS]=WalkerController->Nmax; iParam[B_MINWALKERS]=WalkerController->Nmin; app_log() << " iParam (old): " <<iparam_old << endl; app_log() << " iParam (new): " <<iParam << endl; app_log() << " vParam (old): " <<vparam_old << endl; app_log() << " vParam (new): " <<vParam << endl; app_log().flush(); // return static_cast<int>(iParam[B_TARGETWALKERS]*1.01/static_cast<double>(nw_target)); return static_cast<int>(round(static_cast<double>(iParam[B_TARGETWALKERS]/static_cast<double>(nw_target)))); }
/* Play a list of audio files. */ int main(int argc, char **argv) { int errorStatus = 0; int i; int c; int cnt; int file_type; int rem; int outsiz; int tsize; int len; int err; int ifd; int stdinseen; int regular; int swapBytes; int frame; char *outbuf; caddr_t mapaddr; struct stat st; char *cp; char ctldev[MAXPATHLEN]; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); /* Get the program name */ prog = strrchr(argv[0], '/'); if (prog == NULL) prog = argv[0]; else prog++; Stdin = MGET("(stdin)"); /* Check AUDIODEV environment for audio device name */ if (cp = getenv("AUDIODEV")) { Audio_dev = cp; } /* Parse the command line arguments */ err = 0; while ((i = getopt(argc, argv, prog_opts)) != EOF) { switch (i) { case 'v': if (parse_unsigned(optarg, &Volume, "-v")) { err++; } else if (Volume > MAX_GAIN) { Error(stderr, MGET("%s: invalid value " "for -v\n"), prog); err++; } break; case 'd': Audio_dev = optarg; break; case 'V': Verbose = TRUE; break; case 'E': Errdetect = TRUE; break; case 'i': Immediate = TRUE; break; case '?': usage(); /*NOTREACHED*/ } } if (err > 0) exit(1); argc -= optind; /* update arg pointers */ argv += optind; /* Validate and open the audio device */ err = stat(Audio_dev, &st); if (err < 0) { Error(stderr, MGET("%s: cannot stat "), prog); perror(Audio_dev); exit(1); } if (!S_ISCHR(st.st_mode)) { Error(stderr, MGET("%s: %s is not an audio device\n"), prog, Audio_dev); exit(1); } /* This should probably use audio_cntl instead of open_audio */ if ((argc <= 0) && isatty(fileno(stdin))) { Error(stderr, MGET("%s: No files and stdin is a tty.\n"), prog); exit(1); } /* Check on the -i status now. */ Audio_fd = open(Audio_dev, O_WRONLY | O_NONBLOCK); if ((Audio_fd < 0) && (errno == EBUSY)) { if (Immediate) { Error(stderr, MGET("%s: %s is busy\n"), prog, Audio_dev); exit(1); } } (void) close(Audio_fd); Audio_fd = -1; /* Try to open the control device and save the current format */ (void) snprintf(ctldev, sizeof (ctldev), "%sctl", Audio_dev); Audio_ctlfd = open(ctldev, O_RDWR); if (Audio_ctlfd >= 0) { /* * wait for the device to become available then get the * controls. We want to save the format that is left when the * device is in a quiescent state. So wait until then. */ Audio_fd = open(Audio_dev, O_WRONLY); (void) close(Audio_fd); Audio_fd = -1; if (audio_get_play_config(Audio_ctlfd, &Save_hdr) != AUDIO_SUCCESS) { (void) close(Audio_ctlfd); Audio_ctlfd = -1; } } /* store AUDIOPATH so we don't keep doing getenv() */ Audio_path = getenv("AUDIOPATH"); /* Set up SIGINT handler to flush output */ (void) signal(SIGINT, sigint); /* Set the endian nature of the machine. */ if ((ulong_t)1 != htonl((ulong_t)1)) { NetEndian = FALSE; } /* If no filenames, read stdin */ stdinseen = FALSE; if (argc <= 0) { Ifile = Stdin; } else { Ifile = *argv++; argc--; } /* Loop through all filenames */ do { /* Interpret "-" filename to mean stdin */ if (strcmp(Ifile, "-") == 0) Ifile = Stdin; if (Ifile == Stdin) { if (stdinseen) { Error(stderr, MGET("%s: stdin already processed\n"), prog); goto nextfile; } stdinseen = TRUE; ifd = fileno(stdin); } else { if ((ifd = path_open(Ifile, O_RDONLY, 0, Audio_path)) < 0) { Error(stderr, MGET("%s: cannot open "), prog); perror(Ifile); errorStatus++; goto nextfile; } } /* Check to make sure this is an audio file */ err = audio_read_filehdr(ifd, &File_hdr, &file_type, (char *)NULL, 0); if (err != AUDIO_SUCCESS) { Error(stderr, MGET("%s: %s is not a valid audio file\n"), prog, Ifile); errorStatus++; goto closeinput; } /* If G.72X adpcm, set flags for conversion */ if ((File_hdr.encoding == AUDIO_ENCODING_G721) && (File_hdr.samples_per_unit == 2) && (File_hdr.bytes_per_unit == 1)) { Decode = AUDIO_ENCODING_G721; File_hdr.encoding = AUDIO_ENCODING_ULAW; File_hdr.samples_per_unit = 1; File_hdr.bytes_per_unit = 1; adpcm_state = (struct audio_g72x_state *)malloc (sizeof (*adpcm_state) * File_hdr.channels); for (i = 0; i < File_hdr.channels; i++) { g721_init_state(&adpcm_state[i]); } } else if ((File_hdr.encoding == AUDIO_ENCODING_G723) && (File_hdr.samples_per_unit == 8) && (File_hdr.bytes_per_unit == 3)) { Decode = AUDIO_ENCODING_G723; File_hdr.encoding = AUDIO_ENCODING_ULAW; File_hdr.samples_per_unit = 1; File_hdr.bytes_per_unit = 1; adpcm_state = (struct audio_g72x_state *)malloc (sizeof (*adpcm_state) * File_hdr.channels); for (i = 0; i < File_hdr.channels; i++) { g723_init_state(&adpcm_state[i]); } } else { Decode = AUDIO_ENCODING_NONE; } /* Check the device configuration */ open_audio(); if (audio_cmp_hdr(&Dev_hdr, &File_hdr) != 0) { /* * The device does not match the input file. * Wait for any old output to drain, then attempt * to reconfigure the audio device to match the * input data. */ if (audio_drain(Audio_fd, FALSE) != AUDIO_SUCCESS) { /* Flush any remaining audio */ (void) ioctl(Audio_fd, I_FLUSH, FLUSHW); Error(stderr, MGET("%s: "), prog); perror(MGET("AUDIO_DRAIN error")); exit(1); } /* Flush any remaining audio */ (void) ioctl(Audio_fd, I_FLUSH, FLUSHW); if (!reconfig()) { errorStatus++; goto closeinput; } } /* try to do the mmaping - for regular files only ... */ err = fstat(ifd, &st); if (err < 0) { Error(stderr, MGET("%s: cannot stat "), prog); perror(Ifile); exit(1); } regular = (S_ISREG(st.st_mode)); /* If regular file, map it. Else, allocate a buffer */ mapaddr = 0; /* * This should compare to MAP_FAILED not -1, can't * find MAP_FAILED */ if (regular && ((mapaddr = mmap(0, st.st_size, PROT_READ, MAP_SHARED, ifd, 0)) != MAP_FAILED)) { (void) madvise(mapaddr, st.st_size, MADV_SEQUENTIAL); /* Skip the file header and set the proper size */ cnt = lseek(ifd, 0, SEEK_CUR); if (cnt < 0) { perror("lseek"); exit(1); } inbuf = (unsigned char *) mapaddr + cnt; len = cnt = st.st_size - cnt; } else { /* Not a regular file, or map failed */ /* mark is so. */ mapaddr = 0; /* Allocate buffer to hold 10 seconds of data */ cnt = BUFFER_LEN * File_hdr.sample_rate * File_hdr.bytes_per_unit * File_hdr.channels; if (bufsiz != cnt) { if (buf != NULL) { (void) free(buf); } buf = (unsigned char *) malloc(cnt); if (buf == NULL) { Error(stderr, MGET("%s: couldn't allocate %dK " "buf\n"), prog, bufsiz / 1000); exit(1); } inbuf = buf; bufsiz = cnt; } } /* Set buffer sizes and pointers for conversion, if any */ switch (Decode) { default: case AUDIO_ENCODING_NONE: insiz = bufsiz; outbuf = (char *)buf; break; case AUDIO_ENCODING_G721: insiz = ADPCM_SIZE / 2; outbuf = (char *)adpcm_buf; initmux(1, 2); break; case AUDIO_ENCODING_G723: insiz = (ADPCM_SIZE * 3) / 8; outbuf = (char *)adpcm_buf; initmux(3, 8); break; } /* * 8-bit audio isn't a problem, however 16-bit audio is. * If the file is an endian that is different from the machine * then the bytes will need to be swapped. * * Note: Because the G.72X conversions produce 8bit output, * they don't require a byte swap before display and so * this scheme works just fine. If a conversion is added * that produces a 16 bit result and therefore requires * byte swapping before output, then a mechanism * for chaining the two conversions will have to be built. * * Note: The following if() could be simplified, but then * it gets to be very hard to read. So it's left as is. */ if (File_hdr.bytes_per_unit == 2 && ((!NetEndian && file_type == FILE_AIFF) || (!NetEndian && file_type == FILE_AU) || (NetEndian && file_type == FILE_WAV))) { swapBytes = TRUE; } else { swapBytes = FALSE; } if (swapBytes) { /* Read in interal number of sample frames. */ frame = File_hdr.bytes_per_unit * File_hdr.channels; insiz = (SWAP_SIZE / frame) * frame; /* make the output buffer the swap buffer. */ outbuf = (char *)swap_buf; } /* * At this point, we're all ready to copy the data. */ if (mapaddr == 0) { /* Not mmapped, do it a buffer at a time. */ inbuf = buf; frame = File_hdr.bytes_per_unit * File_hdr.channels; rem = 0; while ((cnt = read(ifd, inbuf+rem, insiz-rem)) >= 0) { /* * We need to ensure only an integral number of * samples is ever written to the audio device. */ cnt = cnt + rem; rem = cnt % frame; cnt = cnt - rem; /* * If decoding adpcm, or swapping bytes do it * now. * * We treat the swapping like a separate * encoding here because the G.72X encodings * decode to single byte output samples. If * another encoding is added and it produces * multi-byte output samples this will have to * be changed. */ if (Decode == AUDIO_ENCODING_G721) { outsiz = 0; demux(1, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g721_decode(in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error decoding g721\n"), prog); errorStatus++; break; } } mux(outbuf); cnt = outsiz; } else if (Decode == AUDIO_ENCODING_G723) { outsiz = 0; demux(3, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g723_decode(in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error decoding g723\n"), prog); errorStatus++; break; } } mux(outbuf); cnt = outsiz; } else if (swapBytes) { swab((char *)inbuf, outbuf, cnt); } /* If input EOF, write an eof marker */ err = write(Audio_fd, outbuf, cnt); if (err < 0) { perror("write"); errorStatus++; break; } else if (err != cnt) { Error(stderr, MGET("%s: output error: "), prog); perror(""); errorStatus++; break; } if (cnt == 0) { break; } /* Move remainder to the front of the buffer */ if (rem != 0) { (void *)memcpy(inbuf, inbuf + cnt, rem); } } if (cnt < 0) { Error(stderr, MGET("%s: error reading "), prog); perror(Ifile); errorStatus++; } } else { /* We're mmaped */ if ((Decode != AUDIO_ENCODING_NONE) || swapBytes) { /* Transform data if we have to. */ for (i = 0; i <= len; i += cnt) { cnt = insiz; if ((i + cnt) > len) { cnt = len - i; } if (Decode == AUDIO_ENCODING_G721) { outsiz = 0; demux(1, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g721_decode( in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error decoding " "g721\n"), prog); errorStatus++; break; } } mux(outbuf); } else if (Decode == AUDIO_ENCODING_G723) { outsiz = 0; demux(3, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g723_decode( in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error " "decoding g723\n"), prog); errorStatus++; break; } } mux(outbuf); } else if (swapBytes) { swab((char *)inbuf, outbuf, cnt); outsiz = cnt; } inbuf += cnt; /* If input EOF, write an eof marker */ err = write(Audio_fd, (char *)outbuf, outsiz); if (err < 0) { perror("write"); errorStatus++; } else if (outsiz == 0) { break; } } } else { /* write the whole thing at once! */ err = write(Audio_fd, inbuf, len); if (err < 0) { perror("write"); errorStatus++; } if (err != len) { Error(stderr, MGET("%s: output error: "), prog); perror(""); errorStatus++; } err = write(Audio_fd, inbuf, 0); if (err < 0) { perror("write"); errorStatus++; } } } /* Free memory if decoding ADPCM */ switch (Decode) { case AUDIO_ENCODING_G721: case AUDIO_ENCODING_G723: freemux(); break; default: break; } closeinput:; if (mapaddr != 0) (void) munmap(mapaddr, st.st_size); (void) close(ifd); /* close input file */ if (Errdetect) { cnt = 0; audio_set_play_error(Audio_fd, (unsigned int *)&cnt); if (cnt) { Error(stderr, MGET("%s: output underflow in %s\n"), Ifile, prog); errorStatus++; } } nextfile:; } while ((argc > 0) && (argc--, (Ifile = *argv++) != NULL)); /* * Though drain is implicit on close(), it's performed here * to ensure that the volume is reset after all output is complete. */ (void) audio_drain(Audio_fd, FALSE); /* Flush any remaining audio */ (void) ioctl(Audio_fd, I_FLUSH, FLUSHW); if (Volume != INT_MAX) (void) audio_set_play_gain(Audio_fd, &Savevol); if ((Audio_ctlfd >= 0) && (audio_cmp_hdr(&Save_hdr, &Dev_hdr) != 0)) { (void) audio_set_play_config(Audio_fd, &Save_hdr); } (void) close(Audio_fd); /* close output */ return (errorStatus); }
bool KSSL::setSettings(KSSLSettings *settings) { delete m_cfg; m_cfg = settings; return reconfig(); }
void uloop() { FENCEBOXPTR fence ; CBOXPTR acellptr, bcellptr ; BBOXPTR ablckptr , bblckptr ; INT flips , rejects , do_single_cell_move , bit_class ; INT axcenter , bxcenter , bycenter ; INT aorient , borient ; INT blk , pairflips ; INT i , j , t , count , swaps, index, shift ; INT abin , bbin , fds , done , single_swap ; DOUBLE target_row_penalty ; DOUBLE target_bin_penalty ; DOUBLE temp , percent_error ; DOUBLE dCp, delta , gswap_ratio ; INT m1,m2, trials ; INT num_accepts , gate_switches , gate_attempts ; INT last_flips , delta_func , delta_time ; INT temp_timer, time_to_update ; /* keeps track of when to update T */ DOUBLE iter_time, accept_deviation, calc_acceptance_ratio() ; DOUBLE num_time, num_func ; DOUBLE calc_time_factor() ; /* commented out variables INT reset_T ; DOUBLE old_T ; */ attemptsG = 0 ; flips = 0 ; rejects = 0 ; pairflips = 0 ; earlyRejG = 0 ; Rej_errorG = 0 ; G( reset_heat_index() ) ; potential_errorsG = 0 ; error_countG = 0 ; if( !P_limit_setS || iterationG <= 0 ) { P_limitG = 999999; if( iterationG > 0 ) { P_limit_setS = TRUE ; } } else { if( wire_chgsG > 0 ) { mean_wire_chgG = total_wire_chgG / (DOUBLE) wire_chgsG ; if( iterationG > 1 ) { sigma_wire_chgG = sqrt( sigma_wire_chgG / (DOUBLE) wire_chgsG); } else { sigma_wire_chgG = 3.0 * mean_wire_chgG ; } } else { mean_wire_chgG = 0.0 ; sigma_wire_chgG = 0.0 ; } P_limitG = mean_wire_chgG + 3.0 * sigma_wire_chgG + TG ; if (P_limitG > 999999) P_limitG = 999999; } sigma_wire_chgG = 0.0 ; total_wire_chgG = 0.0 ; wire_chgsG = 0 ; m1 = m2 = 1; dCp = 0.0; fds = reconfig() ; avg_rowpenalS = 0.0 ; num_penalS = 0.0 ; if( iterationG < 0 ) { avg_timeG = 0.0 ; num_time = 0.0 ; avg_funcG = 0.0 ; num_func = 0.0 ; } /* number of moves before temperature update */ time_to_update = attmaxG / NUMTUPDATES ; if( time_to_update <= 14 ) { time_to_update = 14 ; } temp_timer = 0 ; /* initialize timer */ num_accepts = 0 ; last_flips = 0 ; gate_switches = 0 ; gate_attempts = 0 ; /* ------------------------------------------------------------------------ The back bone of the program the "while-loop" begins from here ... ------------------------------------------------------------------------ */ while( attemptsG < attmaxG ) { /* ------------- pick up a number at random --------------- */ aG = PICK_INT( 1 , numcellsG - extra_cellsG ) ; /* ------------- get the structure for cell# aG ------------- */ acellptr = carrayG[ aG ] ; ablockG = acellptr->cblock ; axcenter = acellptr->cxcenter ; /* ------------------------------------------------------------------------ If two cells have the same swap_group then parts of the cells are interchangable. Below we check if the cell#aG belongs to a swap_group ------------------------------------------------------------------------ */ if( acellptr->num_swap_group > 0 ) { INT sgroup; SGLISTPTR sglistptr; i = PICK_INT( 0 , acellptr->num_swap_group - 1 ) ; sglistptr = acellptr->swapgroups + i; sgroup = sglistptr->swap_group; trials = 0 ; /*--- number of max trials (heuristically)=50 ---*/ do { /* ----------------------------------------------------------------- pick_position picks up a new position for the cell#aG, it returns the bxcenter and blk where the cell could be moved ... -----------------------------------------------------------------*/ pick_position(&bxcenter,&blk,axcenter,ablockG,8.0); bbin = SetBin( bxcenter ) ; /* ----------------------------------------------------------------- the field "cell" in binptrG[blk][bbin]->cell contains a list of all the cells in that bin. But cell[0] contains the total number of cells in the bin (hard-coded) isn't it ... -----------------------------------------------------------------*/ cellbptrG = binptrG[blk][bbin]->cell ; if( *cellbptrG > 0 ) { if( Equal_Width_CellsG ){ BpostG = 1 ; } else { BpostG = PICK_INT( 1 , *cellbptrG ) ; } bG = cellbptrG[ BpostG ] ; bcellptr = carrayG[bG] ; } else { bG = 0 ; } if( bG != 0 && aG != bG ) { for (j = 0; j < bcellptr->num_swap_group; j++) { sglistptr = bcellptr->swapgroups + j; if (sglistptr->swap_group == sgroup) break; } if (j < bcellptr->num_swap_group) { break ; } else { trials++ ; } } else { trials++ ; } } while( trials <= 50 ) ; if( trials <= 50 ) { for( swaps = 1 ; swaps <= 4 ; swaps++ ) { /* -- gate_swap evaluates the proposed gate swaps --*/ gate_switches += gate_swap( 1, i, j ) ; gate_attempts++ ; } } sglistptr = acellptr->swapgroups + i; // If a cell has more than one pin group in the same // swap group, then it can permute pin groups within // itself. if( sglistptr->num_pin_group > 1 ) { for( swaps = 1 ; swaps <= 4 ; swaps++ ) { gate_swap( 0, i, j ) ; } } } if( acellptr->cclass < -1 ) { /*---- for rigid cells, continue ----*/ continue ; } ablckptr = barrayG[ ablockG ] ; aorient = acellptr->corient ; abin = SetBin( axcenter ) ; cellaptrG = binptrG[ablockG][abin]->cell ; if( Equal_Width_CellsG ){ ApostG = 1 ; } else { for( i = 1 ; i <= *cellaptrG ; i++ ) { if( cellaptrG[i] == aG ) { ApostG = i ; break ; } } } /* * select block for cell a to be placed in */ if( acellptr->fence == NULL ) { /* cclass -1 cells won't enter here */ bblockG = 0 ; for (i=0; i<10; i++) { pick_position(&bxcenter,&blk,axcenter,ablockG,1.0); bblckptr = barrayG[ blk ] ; /* if cell "a" can't legally enter this row, keep looking */ if( ablockG == blk || acellptr->cclass == 0 ) { /* cell "a" will remain in the same row, or: */ /* cell "a" can go anywhere it pleases */ break ; } else if( acellptr->cclass > 0 ) { /* it cannot go anywhere it pleases */ bit_class = 1 ; index = (bblckptr->bclass - 1) / 32 ; shift = bblckptr->bclass - 32 * index ; bit_class <<= (shift - 1) ; if( bit_class & acellptr->cbclass[index] ) { /* "a" is allowed in a row with this block_class */ break ; } /* else, keep searching for a legal row */ } } } else { /* * select block for cell a to be placed in */ bblockG = 0 ; for (i=0; i<10; i++) { fence = acellptr->fence ; if( fence->next_fence != NULL ) { count = 0 ; for( ; fence; fence = fence->next_fence){ count++ ; } j = PICK_INT( 1 , count ) ; count = 0 ; fence = acellptr->fence ; for( ; fence; fence = fence->next_fence ) { if( ++count == j ) { break ; } } } pick_fence_position(&bxcenter,&blk,fence) ; bblckptr = barrayG[ blk ] ; /* if cell "a" can't legally enter this row, keep looking */ if( ablockG == blk || acellptr->cclass <= 0 ) { /* cell "a" will remain in the same row, or: */ /* cell "a" can go anywhere it pleases */ break ; } else if( acellptr->cclass > 0 ) { /* it cannot go anywhere it pleases */ bit_class = 1 ; index = (bblckptr->bclass - 1) / 32 ; shift = bblckptr->bclass - 32 * index ; bit_class <<= (shift - 1) ; if( bit_class & acellptr->cbclass[index] ) { /* "a" is allowed in a row with this block_class */ break ; } /* else, keep searching for a legal row */ } } }/* end else -- acellptr->fence != NULL -- cclass -1 cells won't enter here */ if (i == 10) continue; /*-- get out of the while-loop --*/ /*------- Now get the target block's structure and target bin -------*/ bblockG = blk; bycenter = bblckptr->bycenter ; bbin = SetBin( bxcenter ) ; cellbptrG = binptrG[bblockG][bbin]->cell ; if( *cellbptrG > 0 ) { count = 0 ; get_b: if( Equal_Width_CellsG ){ BpostG = 1 ; } else { BpostG = PICK_INT( 1 , *cellbptrG ) ; } bG = cellbptrG[ BpostG ] ; if( aG == bG ) { continue ; } bcellptr = carrayG[bG] ; if( fences_existG ) { done = 0 ; if( (fence = bcellptr->fence) != NULL ) { while(1) { /*------- make sure cell aG's block is outside the block bG's fence -------*/ if( ablockG >= fence->min_block && ablockG <= fence->max_block && axcenter >= fence->min_xpos && axcenter <= fence->max_xpos ) { done = 1 ; break ; } else { fence = fence->next_fence ; if( fence == NULL ) { if( ++count < *cellbptrG ) { goto get_b ; } else { break ; } } } } if( !done ) { continue ; } } } if( bcellptr->cclass < -1 ) { do_single_cell_move = 1 ; } else if( ablockG != bblockG && bcellptr->cclass > 0 ) { bit_class = 1 ; index = (ablckptr->bclass - 1) / 32 ; shift = ablckptr->bclass - 32 * index ; bit_class <<= (shift - 1) ; if( !(bit_class & bcellptr->cbclass[index]) ) { /* "b" is not allowed in a row with this block_class */ continue ; } do_single_cell_move = 0 ; borient = bcellptr->corient ; } else { do_single_cell_move = 0 ; borient = bcellptr->corient ; } } else { do_single_cell_move = 1 ; } delta_func = funccostG ; delta_time = timingcostG ; if( do_single_cell_move ) { if( Equal_Width_CellsG ) { continue ; } /* reset_T = 0 ; if( acellptr->fence != NULL ) { if( ablockG < acellptr->fence->min_block || ablockG > acellptr->fence->max_block ) { reset_T = 1 ; old_T = T ; T = 1000000.0 ; } } */ if( ablckptr->borient == 1 ) { if( bblckptr->borient == 1 ) { t = ucxx1( bxcenter, bycenter) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } else { /* bblckptr->borient == 2 */ t = ucxxo1( bxcenter,bycenter,(aorient == 0) ? 1 : 3 ) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } } else { /* ablockGptr->borient == 2 */ if( bblckptr->borient == 1 ) { t = ucxxo1( bxcenter, bycenter, (aorient == 1) ? 0 : 2) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } else { /* bblckptr->borient == 2 */ t = ucxx1( bxcenter, bycenter) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } } /* if( reset_T ) { T = old_T ; } */ } else { /* pairwise interchange */ if( ablckptr->borient == 1 ) { if( bblckptr->borient == 1 ) { t = ucxx2() ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } else { /* bblockG->orient == 2 */ t = ucxxo2( (aorient == 0) ? 1:3, (borient == 1) ? 0:2); if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } } else { /* ablockG->borient == 2 */ if( bblckptr->borient == 1 ) { t = ucxxo2( (aorient == 1) ? 0:2, (borient == 0) ? 1:3); if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } else { /* bblockG->borient == 2 */ t = ucxx2( ) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } } } num_penalS += 1.0 ; avg_rowpenalS = (avg_rowpenalS * (num_penalS - 1.0) + (DOUBLE) rowpenalG) / num_penalS ; attemptsG++ ; /* draw the data */ G( check_graphics(FALSE) ) ; if (iterationG <= 0) { if( iterationG == 0 ) continue; /* calculate a running average of (delta) timing penalty */ delta_time = abs( delta_time - timingcostG ) ; if( delta_time != 0 ) { num_time += 1.0 ; avg_timeG = (avg_timeG * (num_time - 1.0) + (DOUBLE) delta_time) / num_time ; /* calculate a running average of (delta) wirelength penalty */ delta_func = abs( delta_func - funccostG ) ; num_func += 1.0 ; avg_funcG = (avg_funcG * (num_func - 1.0) + (DOUBLE) delta_func) / num_func ; } if (d_costG >= 0){ m1 ++; /* d_cost is the -ve of the actual d_cost */ } else { dCp -= d_costG; m2 ++; } temp = (INITRATIO * attemptsG - m1) / m2; if (temp <= 0.0) { TG *= 0.9; } else { TG = -dCp / (m2 * log(temp)); } continue; /* initialization phase */ } /* ----------------------------------------------------------------- Update temperature using negative feedback to control the acceptance ratio in accordance to curve fit schedule. Calc_acceptance_ratio returns desired acceptance ratio give the iterationG. The damped error term (deviation) is then applied to correct the temperature T. Update_window_size controls the range limiter. We avoid updating T during initialization, we use exact schedule to compute starting T. The temp_timer allows us to update temperature inside the inner loop of the annealing algorithm. We use counter to avoid use of mod function for speed. ------------------------------------------------------------------ */ num_accepts += pairflips + flips - last_flips ; last_flips = pairflips + flips ; if( ++temp_timer >= time_to_update || (attemptsG >= attmaxG && temp_timer >= 50) ) { ratioG = ((DOUBLE)(num_accepts)) / (DOUBLE) temp_timer ; temp_timer = 0 ; /* reset counter */ num_accepts = 0 ; iter_time = (DOUBLE) iterationG + (DOUBLE) attemptsG / (DOUBLE) attmaxG ; accept_deviation = (calc_acceptance_ratio( iter_time ) - ratioG ) ; if( (DOUBLE) iterationG < TURNOFFT ) { accept_deviation *= ACCEPTDAMPFACTOR ; } else { accept_deviation *= ACCEPTDAMPFACTOR2 ; } TG *= 1.0 + accept_deviation ; update_window_size( (DOUBLE) iterationG + (DOUBLE) attemptsG / (DOUBLE) attmaxG ) ; } } /* end of inner loop */ D( "uloop", check_cost() ; ) ;
static void modeset_destroy_fb(int fd, struct modeset_buf *buf) { if (buf->map) { munmap(buf->map, buf->size); } if (buf->fb) { drmModeRmFB(fd, buf->fb); } if (buf->handle) { struct drm_mode_destroy_dumb dreq = { .handle = buf->handle, }; drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); } } static int modeset_create_fb(struct vo *vo, int fd, struct modeset_buf *buf) { int ret = 0; buf->handle = 0; // create dumb buffer struct drm_mode_create_dumb creq = { .width = buf->width, .height = buf->height, .bpp = 32, }; ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq); if (ret < 0) { MP_ERR(vo, "Cannot create dumb buffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } buf->stride = creq.pitch; buf->size = creq.size; buf->handle = creq.handle; // create framebuffer object for the dumb-buffer ret = drmModeAddFB(fd, buf->width, buf->height, 24, 32, buf->stride, buf->handle, &buf->fb); if (ret) { MP_ERR(vo, "Cannot create framebuffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } // prepare buffer for memory mapping struct drm_mode_map_dumb mreq = { .handle = buf->handle, }; ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); if (ret) { MP_ERR(vo, "Cannot map dumb buffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } // perform actual memory mapping buf->map = mmap(0, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset); if (buf->map == MAP_FAILED) { MP_ERR(vo, "Cannot map dumb buffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } memset(buf->map, 0, buf->size); end: if (ret == 0) { return 0; } modeset_destroy_fb(fd, buf); return ret; } static int modeset_find_crtc(struct vo *vo, int fd, drmModeRes *res, drmModeConnector *conn, struct modeset_dev *dev) { for (unsigned int i = 0; i < conn->count_encoders; ++i) { drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[i]); if (!enc) { MP_WARN(vo, "Cannot retrieve encoder %u:%u: %s\n", i, conn->encoders[i], mp_strerror(errno)); continue; } // iterate all global CRTCs for (unsigned int j = 0; j < res->count_crtcs; ++j) { // check whether this CRTC works with the encoder if (!(enc->possible_crtcs & (1 << j))) continue; dev->enc = enc; dev->crtc = enc->crtc_id; return 0; } drmModeFreeEncoder(enc); } MP_ERR(vo, "Connector %u has no suitable CRTC\n", conn->connector_id); return -ENOENT; } static bool is_connector_valid(struct vo *vo, int conn_id, drmModeConnector *conn, bool silent) { if (!conn) { if (!silent) { MP_ERR(vo, "Cannot get connector %d: %s\n", conn_id, mp_strerror(errno)); } return false; } if (conn->connection != DRM_MODE_CONNECTED) { if (!silent) { MP_ERR(vo, "Connector %d is disconnected\n", conn_id); } return false; } if (conn->count_modes == 0) { if (!silent) { MP_ERR(vo, "Connector %d has no valid modes\n", conn_id); } return false; } return true; } static int modeset_prepare_dev(struct vo *vo, int fd, int conn_id, struct modeset_dev **out) { struct modeset_dev *dev = NULL; drmModeConnector *conn = NULL; int ret = 0; *out = NULL; drmModeRes *res = drmModeGetResources(fd); if (!res) { MP_ERR(vo, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno)); ret = -errno; goto end; } if (conn_id == -1) { // get the first connected connector for (int i = 0; i < res->count_connectors; i++) { conn = drmModeGetConnector(fd, res->connectors[i]); if (is_connector_valid(vo, i, conn, true)) { conn_id = i; break; } if (conn) { drmModeFreeConnector(conn); conn = NULL; } } if (conn_id == -1) { MP_ERR(vo, "No connected connectors found\n"); ret = -ENODEV; goto end; } } if (conn_id < 0 || conn_id >= res->count_connectors) { MP_ERR(vo, "Bad connector ID. Max valid connector ID = %u\n", res->count_connectors); ret = -ENODEV; goto end; } conn = drmModeGetConnector(fd, res->connectors[conn_id]); if (!is_connector_valid(vo, conn_id, conn, false)) { ret = -ENODEV; goto end; } dev = talloc_zero(vo->priv, struct modeset_dev); dev->conn = conn->connector_id; dev->front_buf = 0; dev->mode = conn->modes[0]; dev->bufs[0].width = conn->modes[0].hdisplay; dev->bufs[0].height = conn->modes[0].vdisplay; dev->bufs[1].width = conn->modes[0].hdisplay; dev->bufs[1].height = conn->modes[0].vdisplay; MP_INFO(vo, "Connector using mode %ux%u\n", dev->bufs[0].width, dev->bufs[0].height); ret = modeset_find_crtc(vo, fd, res, conn, dev); if (ret) { MP_ERR(vo, "Connector %d has no valid CRTC\n", conn_id); goto end; } for (unsigned int i = 0; i < BUF_COUNT; i++) { ret = modeset_create_fb(vo, fd, &dev->bufs[i]); if (ret) { MP_ERR(vo, "Cannot create framebuffer for connector %d\n", conn_id); for (unsigned int j = 0; j < i; j++) { modeset_destroy_fb(fd, &dev->bufs[j]); } goto end; } } end: if (conn) { drmModeFreeConnector(conn); conn = NULL; } if (res) { drmModeFreeResources(res); res = NULL; } if (ret == 0) { *out = dev; } else { talloc_free(dev); } return ret; } static void modeset_page_flipped(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { struct priv *p = data; p->pflip_happening = false; } static int setup_vo_crtc(struct vo *vo) { struct priv *p = vo->priv; if (p->active) return 0; p->old_crtc = drmModeGetCrtc(p->fd, p->dev->crtc); int ret = drmModeSetCrtc(p->fd, p->dev->crtc, p->dev->bufs[p->dev->front_buf + BUF_COUNT - 1].fb, 0, 0, &p->dev->conn, 1, &p->dev->mode); p->active = true; return ret; } static void release_vo_crtc(struct vo *vo) { struct priv *p = vo->priv; if (!p->active) return; p->active = false; // wait for current page flip while (p->pflip_happening) { int ret = drmHandleEvent(p->fd, &p->ev); if (ret) { MP_ERR(vo, "drmHandleEvent failed: %i\n", ret); break; } } if (p->old_crtc) { drmModeSetCrtc(p->fd, p->old_crtc->crtc_id, p->old_crtc->buffer_id, p->old_crtc->x, p->old_crtc->y, &p->dev->conn, 1, &p->dev->mode); drmModeFreeCrtc(p->old_crtc); p->old_crtc = NULL; } } static void release_vt(void *data) { struct vo *vo = data; release_vo_crtc(vo); if (USE_MASTER) { //this function enables support for switching to x, weston etc. //however, for whatever reason, it can be called only by root users. //until things change, this is commented. struct priv *p = vo->priv; if (drmDropMaster(p->fd)) { MP_WARN(vo, "Failed to drop DRM master: %s\n", mp_strerror(errno)); } } } static void acquire_vt(void *data) { struct vo *vo = data; if (USE_MASTER) { struct priv *p = vo->priv; if (drmSetMaster(p->fd)) { MP_WARN(vo, "Failed to acquire DRM master: %s\n", mp_strerror(errno)); } } setup_vo_crtc(vo); } static int wait_events(struct vo *vo, int64_t until_time_us) { struct priv *p = vo->priv; int64_t wait_us = until_time_us - mp_time_us(); int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); vt_switcher_poll(&p->vt_switcher, timeout_ms); return 0; } static void wakeup(struct vo *vo) { struct priv *p = vo->priv; vt_switcher_interrupt_poll(&p->vt_switcher); } static int reconfig(struct vo *vo, struct mp_image_params *params, int flags) { struct priv *p = vo->priv; vo->dwidth = p->device_w; vo->dheight = p->device_h; vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd); int32_t w = p->dst.x1 - p->dst.x0; int32_t h = p->dst.y1 - p->dst.y0; // p->osd contains the parameters assuming OSD rendering in window // coordinates, but OSD can only be rendered in the intersection // between window and video rectangle (i.e. not into panscan borders). p->osd.w = w; p->osd.h = h; p->osd.mt = MPMIN(0, p->osd.mt); p->osd.mb = MPMIN(0, p->osd.mb); p->osd.mr = MPMIN(0, p->osd.mr); p->osd.ml = MPMIN(0, p->osd.ml); p->x = (p->device_w - w) >> 1; p->y = (p->device_h - h) >> 1; mp_sws_set_from_cmdline(p->sws, vo->opts->sws_opts); p->sws->src = *params; p->sws->dst = (struct mp_image_params) { .imgfmt = IMGFMT_BGR0, .w = w, .h = h, .d_w = w, .d_h = h, }; talloc_free(p->cur_frame); p->cur_frame = mp_image_alloc(IMGFMT_BGR0, p->device_w, p->device_h); mp_image_params_guess_csp(&p->sws->dst); mp_image_set_params(p->cur_frame, &p->sws->dst); struct modeset_buf *buf = p->dev->bufs; memset(buf[0].map, 0, buf[0].size); memset(buf[1].map, 0, buf[1].size); if (mp_sws_reinit(p->sws) < 0) return -1; vo->want_redraw = true; return 0; } static void draw_image(struct vo *vo, mp_image_t *mpi) { struct priv *p = vo->priv; if (p->active) { struct mp_image src = *mpi; struct mp_rect src_rc = p->src; src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, mpi->fmt.align_x); src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, mpi->fmt.align_y); mp_image_crop_rc(&src, src_rc); mp_sws_scale(p->sws, p->cur_frame, &src); osd_draw_on_image(vo->osd, p->osd, src.pts, 0, p->cur_frame); struct modeset_buf *front_buf = &p->dev->bufs[p->dev->front_buf]; int32_t shift = (p->device_w * p->y + p->x) * 4; memcpy_pic(front_buf->map + shift, p->cur_frame->planes[0], (p->dst.x1 - p->dst.x0) * 4, p->dst.y1 - p->dst.y0, p->device_w * 4, p->cur_frame->stride[0]); } if (mpi != p->last_input) { talloc_free(p->last_input); p->last_input = mpi; } } static void flip_page(struct vo *vo) { struct priv *p = vo->priv; if (!p->active || p->pflip_happening) return; int ret = drmModePageFlip(p->fd, p->dev->crtc, p->dev->bufs[p->dev->front_buf].fb, DRM_MODE_PAGE_FLIP_EVENT, p); if (ret) { MP_WARN(vo, "Cannot flip page for connector\n"); } else { p->dev->front_buf++; p->dev->front_buf %= BUF_COUNT; p->pflip_happening = true; } // poll page flip finish event const int timeout_ms = 3000; struct pollfd fds[1] = { { .events = POLLIN, .fd = p->fd }, }; poll(fds, 1, timeout_ms); if (fds[0].revents & POLLIN) { ret = drmHandleEvent(p->fd, &p->ev); if (ret != 0) { MP_ERR(vo, "drmHandleEvent failed: %i\n", ret); return; } } } static void uninit(struct vo *vo) { struct priv *p = vo->priv; if (p->dev) { release_vo_crtc(vo); modeset_destroy_fb(p->fd, &p->dev->bufs[1]); modeset_destroy_fb(p->fd, &p->dev->bufs[0]); drmModeFreeEncoder(p->dev->enc); } vt_switcher_destroy(&p->vt_switcher); talloc_free(p->last_input); talloc_free(p->cur_frame); talloc_free(p->dev); close(p->fd); } static int preinit(struct vo *vo) { struct priv *p = vo->priv; p->sws = mp_sws_alloc(vo); p->fd = -1; p->ev.version = DRM_EVENT_CONTEXT_VERSION; p->ev.page_flip_handler = modeset_page_flipped; if (vt_switcher_init(&p->vt_switcher, vo->log)) goto err; vt_switcher_acquire(&p->vt_switcher, acquire_vt, vo); vt_switcher_release(&p->vt_switcher, release_vt, vo); if (modeset_open(vo, &p->fd, p->device_path)) goto err; if (modeset_prepare_dev(vo, p->fd, p->connector_id, &p->dev)) goto err; assert(p->dev); p->device_w = p->dev->bufs[0].width; p->device_h = p->dev->bufs[0].height; if (setup_vo_crtc(vo)) { MP_ERR(vo, "Cannot set CRTC for connector %u: %s\n", p->connector_id, mp_strerror(errno)); goto err; } return 0; err: uninit(vo); return -1; } static int query_format(struct vo *vo, int format) { return sws_isSupportedInput(imgfmt2pixfmt(format)); } static int control(struct vo *vo, uint32_t request, void *data) { struct priv *p = vo->priv; switch (request) { case VOCTRL_SCREENSHOT_WIN: *(struct mp_image**)data = mp_image_new_copy(p->cur_frame); return VO_TRUE; case VOCTRL_REDRAW_FRAME: draw_image(vo, p->last_input); return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: if (vo->config_ok) reconfig(vo, vo->params, 0); return VO_TRUE; } return VO_NOTIMPL; } #define OPT_BASE_STRUCT struct priv const struct vo_driver video_out_drm = { .name = "drm", .description = "Direct Rendering Manager", .preinit = preinit, .query_format = query_format, .reconfig = reconfig, .control = control, .draw_image = draw_image, .flip_page = flip_page, .uninit = uninit, .wait_events = wait_events, .wakeup = wakeup, .priv_size = sizeof(struct priv), .options = (const struct m_option[]) { OPT_STRING("devpath", device_path, 0), OPT_INT("connector", connector_id, 0), {0}, }, .priv_defaults = &(const struct priv) {