예제 #1
2
파일: testq.cpp 프로젝트: BenjaminYu/gpdb
void* worker(void* d) {
    shared_ptr<UploadBuffer> pdata;
    srand(time(NULL));
    // get data from fq
    while (1) {
        fq.deQ(pdata);

        if (pdata->index == 0) {
            // inited data??
            cout << "inited data" << std::endl;
        }

        if (pdata->index == -1) {  //  finished
            // cout<<"finished"<<std::endl;
            break;
        }

        MD5Calc m;
        m.Update(pdata->data.getdata(), pdata->data.len());
        cout << pdata->index << "\t" << m.Get() << std::endl;
        // sleep(rand()%5);

        // reset pdata
        pdata->data.reset();
        pdata->index = 0;

        // re queue to empty queue
        eq.enQ(pdata);
    }
    // cout<<"quit...\n";
}
예제 #2
1
void child() {
    for (int i=1; i<=max_num; i++) {
        cq.push(i);
    }
    // Queue is closed only if all child threads are finished
    if(bar.wait()) cq.close();
}
예제 #3
0
파일: await_emu.cpp 프로젝트: ElaraFX/boost
int main()
{
    srand(time(0));

    // Custom scheduling is not required - can be integrated
    // to other systems transparently
    main_tasks.push([]
    {
        asynchronous([]
        {
            return async_user_handler(),
                   finished = true;
        });
    });

    Task task;
    while(!finished)
    {
        main_tasks.pop(task);
        task();
    }

    cout << "Done" << std::endl;

    return EXIT_SUCCESS;
}
예제 #4
0
파일: ccr.cpp 프로젝트: DaiYamatta/ALua
static void* ccr_worker(void *arg)
{
    int r, resume;
    process_t *proc;
    while (1)
    {
        // Checks if threads need to be killed and the the ready procces's queue is empty
        // That way only when the queue is empty the threads are killed
        // if ((free_flag.compare_and_swap(false, true)) && (prc_ready.empty()))
        if (free_flag.compare_and_swap(false, true))
        {
            pthread_t thread = pthread_self();
            // removes reference from the pool
            thr_pool.remove(thread);

            // checks if threre's more threads to kill and set the flag
            if (free_workers.fetch_and_decrement() > 1)
            {
                free_flag.compare_and_swap(true, false);
            }

            //kills the current thread
            pthread_exit(NULL);
        }
        prc_ready.pop(proc);
        if (!proc) return NULL;
        r = lua_resume(proc->L, 0);
        switch (r)
        {
            case  LUA_YIELD:
                //cerr << "Yield!\n";
                switch (proc->status)
                {
                    case PS_READY:
                        // releasing the lock acquired in ccr_yield
                        proc->wlock.release();
                        prc_ready.push(proc);
                        break;
                    case PS_BLOCKING:
                        proc->status = PS_BLOCKED;
                        // releasing the lock acquired in ccr_yield
                        proc->wlock.release();
                        break;
                }
                break;
            case LUA_ERRRUN:
            case LUA_ERRMEM:
            case LUA_ERRERR:
                cerr << "[ERROR][PROCESSING A LUA PROCESS] " << lua_tostring(proc->L, -1) << endl;
                // fall-through
            case 0:
                lua_close(proc->L);
                mbx_close(proc->mbox);
                prc_free(proc);
                break;
        }
    }
    return NULL;
}
예제 #5
0
 //! Get pair of matricies if present
 bool pop_if_present( pair<Matrix2x2, Matrix2x2> &mm ) {
     // get first matrix if present
     if(!Queue.pop_if_present(mm.first)) return false;
     // get second matrix if present
     if(!Queue.pop_if_present(mm.second)) {
         // if not, then push back first matrix
         Queue.push(mm.first); return false;
     }
     return true;
 }
예제 #6
0
void producer(std::atomic<bool>& keep_working, concurrent_queue<std::vector<char> >& sink)
{
    while (keep_working.load())
    {
        if (sink.size() > 10000)
            std::this_thread::yield();
        else
            sink.push(std::vector<char>(rand() % 10000));
    }
}
예제 #7
0
int main(int argc, char*argv[])
{
    size_t nElements = 1280000;
    size_t nthreads = 1;
    struct timeval start, stop;

    if (argc >= 2) {
        nthreads = atoi(argv[1]);
    }
    if (argc >= 3) {
        nElements = atoi(argv[2]);
    }
    if (argc >= 4) {
        objsize = atoi(argv[3]);
    }

    task_scheduler_init init(nthreads);

    for (uintptr_t i = 0; i < nElements; i++) {
        cq.push((void*)i);
    }
    for (uintptr_t i = 0; i < nElements; i++) {
        void* j;
        cq.try_pop(j);
        assert(i == (uintptr_t)j);
    }
    assert(cq.empty());

    tick_count t0 = tick_count::now();
    parallel_for(blocked_range<size_t>(0, nElements), loop_queuer());
    tick_count t1 = tick_count::now();
    printf("queue time: %f secs\n", (t1 - t0).seconds());

    t0 = tick_count::now();
    parallel_for(blocked_range<size_t>(0, nElements), loop_dequeuer());
    t1 = tick_count::now();
    printf("dequeue time: %f secs\n", (t1 - t0).seconds());

    assert(cq.empty());

    t0 = tick_count::now();
    parallel_for(blocked_range<size_t>(0, nElements), loop_queuer());
    parallel_for(blocked_range<size_t>(0, nElements), loop_dequeuer());
    t1 = tick_count::now();
    printf("both time: %f secs\n", (t1 - t0).seconds());

    assert(cq.empty());

    printf("success!\n");
    return 0;
}
예제 #8
0
 //! executing filter
 /*override*/ void* operator()(void*)
 {
     int n = --N;
     if(n <= 0) return 0;
     Queue.push( Matrix1110 );
     return &Queue;
 }
예제 #9
0
void *worker(void *a) {
    int r;
    while (1) {
        q.deQ(r);
        if (r == -1) break;
    }
    return NULL;
}
예제 #10
0
TEST(queue, simple) {
    pthread_t thread_id[num_threads];
    for (int tnum = 0; tnum < num_threads; tnum++) {
        pthread_create(&thread_id[tnum], NULL, &worker, NULL);
    }
    int r = 1024;
    while (r--) {
        q.enQ(r);
    }

    for (int i = 0; i < num_threads; i++) {
        q.enQ(-1);
    }

    for (int i = 0; i < num_threads; i++) {
        pthread_join(thread_id[i], NULL);
    }
}
예제 #11
0
    void operator() (const blocked_range<size_t>&r) const
    {
        size_t begin = r.begin();
        size_t end = r.end();

        for (size_t i = begin; i < end; i++) {
            void * tmp = tbballoc.allocate(1);
            memset(tmp, 1, objsize);
            cq.push(tmp);
        }
    }
예제 #12
0
파일: ccr.cpp 프로젝트: DaiYamatta/ALua
int ccr_rawsend(process_t *proc, message_t *msg)
{
    queuing_rw_mutex::scoped_lock rlock;
    rlock.acquire(proc->lock, false);
    if (mbx_put(proc->mbox, msg))
    {
        if (proc->status.compare_and_swap(PS_READY, PS_BLOCKED) == PS_BLOCKED)
            prc_ready.push(proc);
        rlock.release();
        return 1;
    }
    rlock.release();
    return 0;
}
예제 #13
0
void writefn(std::string outaudio, std::string outdiff)
{
	std::ofstream oaudio(outaudio, std::ios::binary);
	//int fourcc = CV_FOURCC('4', '6', '2', 'H');
	int fourcc = -1;
	std::cout << "creating VideoWriter\n";
	std::cout << "fps " << vid_fps << ", reduction " << reduction << "\n";
	cv::VideoWriter odiff(outdiff.c_str(), fourcc, vid_fps / reduction, cv::Size(width, height), true);
	//cv::VideoWriter omask(outmask.c_str(), fourcc, vid_fps / reduction, cv::Size(width, height), true);
	std::cout << "done creating VideoWriter\n";

	WriteElement element;

	while (true)
	{
		bool rv = writequeue.try_pop(element);
		if (!rv) continue;

		if (element.done) break;

		// video

		odiff.write(element.mat);

		// audio

		int u = (int)iround(audiorate * (element.frameno + 0) / (vid_fps / reduction));
		int v = (int)iround(audiorate * (element.frameno + 1) / (vid_fps / reduction));
		int nsamples = v - u;
		std::vector<int16_t> samples(nsamples, 0);

		for (int k = 0; k < nsamples; k += 1)
			samples[k] = sin(audiofreq * 2 * M_PI / audiorate * (u + k))
			* ((1<<15)-1)
			* linmap(20 * log10(element.masksum), -90.0, 0.0, 0.0, 1.0);

		oaudio.write((char*)samples.data(), sizeof(samples[0]) * nsamples);

	}

	odiff.release();
	oaudio.close();

	std::cout << "writer is done\n";
}
예제 #14
0
    void operator() (const blocked_range<size_t>&r) const
    {
        size_t begin = r.begin();
        size_t end = r.end();
        void * ref = tbballoc.allocate(1);

        memset(ref, 1, objsize);
        for (size_t i = begin; i < end; i++) {
            void* j;
            cq.try_pop(j);
            assert(NULL != j);
            if (memcmp(ref, j, objsize)) {
                fprintf(stderr, "memory was corrupted!\n");
                exit(-3);
            }
            tbballoc.deallocate((bigobj<1024>*)j, 0);
        }
    }
예제 #15
0
파일: ccr.cpp 프로젝트: DaiYamatta/ALua
static int ccr_finalize(lua_State *L)
{
    int i;
    process_t *proc;
    lua_getfield(L, LUA_REGISTRYINDEX, CCR_SELF);
    proc = (process_t*)lua_touserdata(L, -1);
    if (proc->main)
    {
        for (i = 0; i < THR_SIZE; i++)
        {
            prc_ready.push(NULL);
        }

        for (list<pthread_t>::iterator thread = thr_pool.begin(); thread!=thr_pool.end(); ++thread)
        {
            pthread_join(*thread, NULL);
        }
    }
    return 0;
}
예제 #16
0
파일: ccr.cpp 프로젝트: DaiYamatta/ALua
static int ccr_spawn(lua_State *L)
{
    process_t *proc;
    const char *str = luaL_checkstring(L, 1);
    proc = new process_t();
    if (proc)
    {
        proc->main = 0;
        proc->counter = 1;
        proc->status = PS_READY;
        proc->mbox = mbx_create();
        if (proc->mbox)
        {
            proc->L = luaL_newstate();
            if (proc->L)
            {
                // luaL_openlibs(proc->L);
                ccr_openlibs(proc->L);
                lua_pushstring(proc->L, CCR_SELF);
                lua_pushlightuserdata(proc->L, proc);
                lua_rawset(proc->L, LUA_REGISTRYINDEX);
                if (!luaL_loadstring(proc->L, str))
                {
                    prc_ready.push(proc);
                    lua_pushboolean(L, 1);
                    return 1;
                }
                cerr << "[ERROR][CREATING LUA PROCESS] " << lua_tostring(proc->L, -1) << endl;
                lua_close(proc->L);
            }
            mbx_free(proc->mbox);
        }
        delete proc;
    }
    lua_pushboolean(L, 0);
    return 1;
}
예제 #17
0
파일: main.cpp 프로젝트: CCJY/coliru
 concurrent( T t_ ) : t{t_}, thd{[=]{ while(!done) q.pop()(); }} { }
예제 #18
0
파일: testq.cpp 프로젝트: BenjaminYu/gpdb
int main(int argc, char* argv[]) {
    vector<pthread_t> threads;
    shared_ptr<UploadBuffer> curdata;

    if (argc < 2) {
        printf("not enough args\n");
        return 1;
    }

    int fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open file fail");
        return 1;
    }

    char* localbuf = (char*)malloc(READLEN);
    int readlen = READLEN;

    for (int tnum = 0; tnum < NUMTHREADS; tnum++) threads.emplace_back();

    for (int tnum = 0; tnum < NUMTHREADS; tnum++) {
        eq.enQ(make_shared<UploadBuffer>(CHUCKSIZE));
    }

    for (int tnum = 0; tnum < NUMTHREADS; tnum++) {
        pthread_create(&threads[tnum], NULL, worker, NULL);
    }

    eq.deQ(curdata);
    // assert (curdata->index == 0)
    int count = 1;
    curdata->index = count++;

    int tmplen;

    while (1) {
        // read data from file
        readlen = read(fd, localbuf, READLEN);
        if (readlen == -1) {
            perror("read fail");
            break;
        } else if (readlen == 0) {  // EOF
            // cout<<"end of file\n";
            if (curdata->index > 0) fq.enQ(curdata);
            break;
        }

        //
        while (1) {
            tmplen = curdata->data.append(localbuf, readlen);
            if (tmplen < readlen) {  // change to next queue, enqueue
                fq.enQ(curdata);
                eq.deQ(curdata);
                curdata->index = count++;

                // assert (curdata->index == 0)
                readlen -= tmplen;
            } else {
                break;  // contineu to read
            }
        }
    }

    printf("Start teardown\n");

    // terminate thread
    for (int tnum = 0; tnum < NUMTHREADS; tnum++) {
        eq.deQ(curdata);
        curdata->index = -1;
        fq.enQ(curdata);
    }
    curdata.reset();
    for (int tnum = 0; tnum < NUMTHREADS; tnum++) {
        pthread_join(threads[tnum], NULL);
    }

    free(localbuf);
    close(fd);
    return 0;
}
예제 #19
0
int comm_request_cs( unsigned int group ) {
  int error = 0;

  // Check to see if the reply is for a group that exists if not skip
  group_map_t::iterator group_it = comm_groups.find( group );
  if ( group_it == comm_groups.end() ) {
  cout << "comm_request_cs Cannot request critical section for group " << group << endl;
    error = -1;
    return error;
  }
  
  // Request critical section for specified group. Record stats for waiting time
  cs_entry_t req;
  req.seq_num = 0;
  req.wait_time = 0;
  req.msg_count = 0;
  CStopWatch timer;
  msg_t      outgoing;
  outgoing.send_ID  = NODE_INFO.id;
  outgoing.dest_ID  = 0;
  outgoing.ts       = comm_seq_num.num;
  outgoing.group_ID = group;
  outgoing.msg_type = MSG_T_REQUEST_CS;
  
  timer.startTimer();
  
  // Lock cs entries so they don't change while reading
  // comm_seq_num.mutex.lock();
  // group_it->second.cs.mutex.lock();
  SHARED_VARS.lock();
  
  group_it->second.cs.requesting = true;
  
  // Update and record sequence numbers
  comm_seq_num.num = comm_seq_num.max_num + 1;
  outgoing.ts = comm_seq_num.num;
  req.seq_num = comm_seq_num.num;  
  
  for ( map<unsigned int, critical_section_t>::iterator it = group_it->second.cs.cs_map.begin();
        it != group_it->second.cs.cs_map.end();
        it++ ) {
    if ( !(it->second.mutex_token) ) {
      req.msg_count++;
      outgoing.dest_ID = it->first;
      comm_send( outgoing );
    }
  }
  
  // Total messages exchanged is always 1 sent + 1 recv = 2*sent
  req.msg_count *= 2;
  
  // group_it->second.cs.mutex.unlock();  
  // comm_seq_num.mutex.unlock();
  SHARED_VARS.unlock();
 
  // If no requests were made, do not wait on any replies
  if ( req.msg_count > 0 ) {
    group_it->second.cs.entry_ok.wait( group_it->second.cs.entry_ok_mutex );
  }
 
  // Record wait time
  timer.stopTimer();
  req.wait_time = timer.getElapsedTime();

  cout << "cs log entry: " << "seq_num " << req.seq_num
       << " wait_time = " << req.wait_time
       << " msg_count = " << req.msg_count << endl;

  comm_cs_log.push( req );
  
  return 0;
}
예제 #20
0
int main()
{
    try
    {
        dExternalDustCurrentOffset = DUST_OFFSET_INIT_VALUE ;
        dExternalDustCurrentMinValue = DUST_MIN_INIT_VALUE ;
        bContinueExecution = true ;

        // Registriamo il segnale interrupt Software del S.O. scatenato con il CTRL+C  e l'handler da evocare a fronte del suo
        // "lancio" da parte del S.O. stesso
        signal( SIGINT , Signal_Callback_Handler ) ;

        // Crea il thread che "consuma" i valori rilevati dai sensori
        thread threadConsumatore( ( CConsumaValoriSensori() ) ) ;
        // Detach perche' la sua esecuzione puo' viaggiare indipendente e noi non dobbiamo conoscerne lo stato
        threadConsumatore.detach() ;

        // Crea il thread per la lettura del sensore I2C interno
        // async per poterne facilmente attendere la chiusura prima del return del main, se si esce con CTRL+C
        future<void> threadI2C = async( launch::async , CReadI2C() ) ;

        // Crea il thread che "tara" i valori rilevati dal sensore delle polveri
        thread threadTaraPolveri( ( CTaratoreValoriPolveri() ) ) ;
        // Detach perche' la sua esecuzione puo' viaggiare indipendente e noi non dobbiamo conoscerne lo stato
        threadTaraPolveri.detach() ;

        CUsbUtils usbUtils ;
        unsigned char pReadBuffer[6] = { 0 , 0 , 0 , 0 , 0 , 0 } ;

        uint16_t nsReadCounter = 0 ;
        /*
        * Misuriamo le polveri ogni 10 ms e temperatura ed umidita' ogni 1000 ms
        */
        while ( bContinueExecution )
        {
            try
            {
                nsReadCounter++ ;

                int nReadedBytes = 0 ;

                if ( usbUtils.Read( pReadBuffer , 6 , &nReadedBytes ) )
                {
                    // Elaborazione della lettura delle polveri
                    uint16_t nsDust = ( pReadBuffer[0] << 8 ) + pReadBuffer[1] ;

                    externalDustMeasurements.push( CUtils::FormatDustValue( nsDust ) ) ;

                    // Se abbiamo raggiunto il valore HUMIDITY_AND_TEMPERATURE_PERIOD_COUNTER del contatore, significa che siamo pronti per
                    // processare anche temperatura ed umidita', oltre alla polvere
		    if ( nsReadCounter == HUMIDITY_AND_TEMPERATURE_PERIOD_COUNTER )
                    {
                        // Elaborazione della lettura della temperatura e dell'umidita' (esterne)
                        uint16_t nsHumidity = ( pReadBuffer[2] << 8 ) + pReadBuffer[3] ;
                        uint16_t nsTemperature = ( pReadBuffer[4] << 8 ) + pReadBuffer[5] ;
					
                        if ( nsHumidity == HUMIDITY_AND_TEMPERATURE_ERR_CODE || nsTemperature == HUMIDITY_AND_TEMPERATURE_ERR_CODE )
                        {
                            CUtils::AddWarningMessage( "Errore nel Sensore di Temperatura e Umidita' del PIC" ) ; 
                        }
                        else 
                        {
                            double dExternalTemperatureCelsius = CUtils::FormatTemperatureValue( nsTemperature ) ;
                            double dExternalHumidityPercentage = CUtils::FormatHumidityValue( nsHumidity ) ;
                            //cout << "Temperatura: " << dExternalTemperatureCelsius ;
                            //cout << " Umidita': " << dExternalHumidityPercentage << endl ;

                            // Aggiungo i valori di temperatura ed umidita'
                            t_HumidityAndTemperatureMeasurementData humidityAndTemperatureMeasurementData ;
                            humidityAndTemperatureMeasurementData.m_dHumidityPercentage = dExternalHumidityPercentage ;
                            humidityAndTemperatureMeasurementData.m_dTemperatureCelsius = dExternalTemperatureCelsius ;
                            externalHumidityAndTemperatureMeasurements.push( humidityAndTemperatureMeasurementData ) ;
                        }

                        nsReadCounter = 0 ;
                    }
                }
                else
                {
                    CUtils::AddWarningMessage( string( "main - usbUtils.Read fallita. VID Device: " ) + to_string( PIC_VID ) + string( " PID Device: " ) + to_string( PIC_PID ) ) ;
                }

                std::chrono::milliseconds sleep_duration( DUST_MEASUREMENT_PERIOD_MS ) ;
                std::this_thread::sleep_for( sleep_duration ) ;
            }
            catch( const exception& e )
            {
                CUtils::AddWarningMessage( "main - Eccezione durante la lettura dei dati dai sensori. Testo: " + string( e.what() ) ) ;
            }
        }

        threadI2C.wait() ;
    }
    catch( const exception& e )
    {
        CUtils::AddWarningMessage( "main - Eccezione generica. Testo: " + string( e.what() ) ) ;
    }

    return 0 ;
}
예제 #21
0
int main(int argc, char **argv)
{
	/*
	cv::Mat foo(50,1, CV_32FC3);
	cv::Mat bar(3,1, CV_32FC1);

	cv::Mat baz = bar.t() * foo.reshape(1).t();
	cout << baz.size() << endl;

	return 0;
	//*/

	parse_args(argc, argv);

	if (videofile.empty())
	{
		std::cout << "no input file given" << std::endl;
		return 0;
	}

	auto vid = new cv::VideoCapture(videofile);

	if (!vid->isOpened())
	{
		std::cerr << "vid could not be opened!" << std::endl;
		delete vid;
		exit(1);
	}

	// build file names
	char buf[1000];
	std::string basename = splitext(videofile);
	sprintf_s(buf, "%s-foreground-r%d%s-b%dx%d-a%g-d%g-s%g-mst%g", 
		basename.c_str(),
		reduction, (blendframes ? "b" : ""),
		blur.x, blur.y,
		alpha_avg,
		alpha_dev,
		sigma_dev,
		masksum_threshold
	);
	std::string outbase(buf);
	if (suffix.length() > 0) outbase += "-" + suffix;

	std::cout << "outbase: " << outbase << std::endl;

	std::string inmaskname(basename + "-inmask.bmp");
	cv::Mat inmask = cv::imread(inmaskname, cv::IMREAD_GRAYSCALE);
	bool const use_inmask = (inmask.data != NULL);
	if (use_inmask)
	{
		std::cout << "using inmask " << inmaskname << std::endl;
		//cv::imshow("inmask", inmask);
	}

	std::string outaudio(outbase + "-audio.raw"); // raw pcm_s16le
	//std::string outmask    (outbase + "-mask.avi");
	std::string outdiff    (outbase + "-maskdiff.avi");

	vid_fps = vid->get(CV_CAP_PROP_FPS);
	width = (int)vid->get(CV_CAP_PROP_FRAME_WIDTH);
	height = (int)vid->get(CV_CAP_PROP_FRAME_HEIGHT);
	nframes = (int)vid->get(CV_CAP_PROP_FRAME_COUNT);

	if (override_fps)
	{
		cout << "fps " << vid_fps << " uncorrected" << endl;
		cout << "nframes " << nframes << " uncorrected" << endl;

		// compensate
		nframes = nframes / vid_fps * override_fps;

		vid_fps = override_fps;
	}
	
	cout << "fps " << vid_fps << endl;
	cout << "nframes " << nframes << endl;

	assert(fmod((double)audiorate, vid_fps) < 1.0);

	cv::Mat frameu8(height, width, CV_8UC3, cv::Scalar::all(0.0f));
	cv::Mat frame(height, width, CV_32FC3, cv::Scalar::all(0.0f));
	cv::Mat gray(height, width, CV_32F, cv::Scalar::all(0.0f));
	cv::Mat average(height, width, CV_32F, cv::Scalar::all(0.0f));
	cv::Mat deviation(height, width, CV_32F, cv::Scalar::all(0.0f));

	ValuePlot plot_avg("plot avg", 640, 360, 0, 640, 0, 1, 0.2);
	
	ValuePlot plot_diff("plot diff", 640, 360, 0, 640, -0.03, 0.03, 1/256.);

	ValuePlot plot_absdiff("plot absdiff", 640, 360, 0, 640, -4, 0, 1);
	plot_absdiff.use_vmap = true;
	plot_absdiff.vmap = [](float v) { return log10(v); };
	
	ValuePlot plot_dev("plot dev", 640, 360, 0, 640, -4, 0);
	plot_dev.use_vmap = true;
	plot_dev.vmap = [](float v) { return log10(v); };

	cv::Mat diff(height, width, CV_32F, cv::Scalar::all(0.0f));
	cv::Mat absdiff(height, width, CV_32F, cv::Scalar::all(0.0f));
	cv::Mat viewdiff(height, width, CV_32F, cv::Scalar::all(0.0f));
	cv::Mat mask(height, width, CV_8U, cv::Scalar::all(0));

	std::thread reader(readfn, vid);
	std::thread writer(writefn, outaudio, outdiff);

#ifdef WIN32
	SetThreadPriority(writer.native_handle(), THREAD_PRIORITY_ABOVE_NORMAL);
#endif

	double sched = hrtimer();
	double dsched = 0.25;

	double statsched = hrtimer();
	double dstat = 1.0;
	double encode_fps = 0.0;
	double encode_alpha = 0.1;
	unsigned lastcount = 0, dcount = 0;

	// DEBUG
	//dstat = 0.0;

	for (int k = 0; k < 5; k += 1)
		donequeue.push(true);

	while (running)
	{
		MatOrNothing item;
		bool success = framequeue.try_pop(item);
		if (!success)
			continue;
		if (!item.anything)
			break;

		// FIXME: compensate for sporadic *fast* whole-image luminance fluctuations (not caught by sigma)
		
		donequeue.push(true);

		frame = item.frame;
		gray = item.gray;
		unsigned frameno = item.frameno;

		if (use_inmask)
			cv::subtract(gray, average, diff, inmask);
		else
			cv::subtract(gray, average, diff);

		cv::add(diff, 0.5, viewdiff);
		absdiff = cv::abs(diff);
		auto diffsum = (cv::sum(absdiff)[0] / (width * height));

		// =====================================================================
		// TODO: histogram: deviation from 'average', bin size = 0.1, -10..+10, y-log

		/*
		a_avg.push_back(cv::sum(diff)[0] / (double)(width * height));
		a_dev.push_back(cv::sum(deviation)[0] / (width * height));
		while (a_avg.size() > a_depth) a_avg.erase(a_avg.begin());
		while (a_dev.size() > a_depth) a_dev.erase(a_dev.begin());

		int histwidth = 500;
		double const emax = 1;
		double const emin = -2;

		a_dev.clear();
		a_dev.resize(histwidth+1, 0);

		for (int y = 0; y < diff.rows; y += 1)
		for (int x = 0; x < diff.cols; x += 1)
		{
			int const bin = 100 + (int)(deviation.at<float>(y,x) / 0.001);

			if (bin < 0) continue;
			if (bin >= a_dev.size()) continue;

			a_dev[bin] += 1;
		}

		for (int k = 0; k < a_dev.size(); k += 1)
			a_dev[k] = a_dev[k] ? log10(a_dev[k]) : -1;

		//*/
		// =====================================================================

		cv::compare(1 / sigma_dev * absdiff, deviation, mask, CV_CMP_GT);
		auto masksum = cv::countNonZero(mask) / (double)(width * height);

		if (masksum > masksum_threshold)
			mask = 0;

		//cv::Mat const mix[] = { mask, mask, mask };
		//cv::Mat mask3;
		//cv::merge(mix, 3, mask3);

		cv::Mat maskviewdiff(height, width, CV_32F, cv::Scalar::all(0.0f));
		maskviewdiff.setTo(cv::Scalar::all(0.5f));
		viewdiff.copyTo(maskviewdiff, mask);

		// =====================================================================
		/*
		{
			cv::Mat foo;

			foo = 1 - deviation / 0.005;
			cv::cvtColor(foo, foo, CV_GRAY2BGR);
			cv::resize(foo, foo, preview_size, 0, 0, CV_INTER_LINEAR);
			
			for (double a = -0.1; a <= 0.1; a += 0.01)
				cv::line(foo, cv::Point(100 + a / 0.001, 200 - 10), cv::Point(100 + a / 0.001, 200 + 10), cv::Scalar::all(0.5), 1);
			
			for (int k = 1; k < a_dev.size(); k += 1)
				cv::line(foo, cv::Point(k - 1, 200 - a_dev[k - 1] / 0.1), cv::Point(k, 200 - a_dev[k] / 0.1), cv::Scalar::all(1), 1);

			for (int k = 1; k < a_avg.size(); k += 1)
				cv::line(foo, cv::Point(k - 1, 200 - a_avg[k - 1] / 0.0001), cv::Point(k, 200 - a_avg[k] / 0.0001), cv::Scalar(1, 0, 0), 1);
			cv::imshow("debug dev", foo);

			foo = 1 - absdiff / 0.005;
			cv::resize(foo, foo, preview_size, 0, 0, CV_INTER_LINEAR);
			cv::imshow("debug diff", foo);
		}
		//*/
		// =====================================================================


		WriteElement const tmp = { false, frameno, maskviewdiff, masksum };
		writequeue.push(tmp);

		if (!headless && sched < hrtimer())
		{
			sched += dsched;

			cv::Mat tmp;

			//cv::Mat display = mask3.clone();
			mask.convertTo(tmp, CV_32F, 1/255.);
			std::ostringstream message;
			message << to_hms(frameno / vid_fps);
			message << ", #" << frameno << " @ " << vid_fps << " fps";
			message << ", mask " << std::fixed << std::setprecision(6) << masksum;
			message << ", diff " << std::fixed << std::setprecision(6) << diffsum;

			cv::putText(tmp, message.str(), cv::Point(5, height - 5), CV_FONT_HERSHEY_PLAIN, width / 600, cv::Scalar::all(1.0), width / 600);
			cv::resize(tmp, tmp, preview_size, 0, 0, CV_INTER_AREA);
			cv::imshow("mask", tmp);

			cv::resize(average, tmp, preview_size, 0, 0, CV_INTER_AREA);
			cv::imshow("average", tmp);

			cv::log(deviation, tmp);
			tmp = tmp * (0.3 / log(10)) + 1.0;
			cv::resize(tmp, tmp, preview_size, 0, 0, CV_INTER_AREA);
			cv::imshow("deviation", tmp);

			/*
			//plot_avg.plot(average);
			plot_absdiff.plot(absdiff);
			plot_diff.plot(diff);
			plot_dev.plot(deviation);
			//*/

			tmp = ((viewdiff - 0.5) * 5) + 0.5;
			cv::resize(tmp, tmp, preview_size, 0, 0, CV_INTER_AREA);
			cv::imshow("diff", tmp);

			cv::resize(maskviewdiff, tmp, preview_size, 0, 0, CV_INTER_AREA);
			cv::imshow("maskdiff", tmp);

			while (true)
			{
				int key = cv::waitKey(1);

				if (key == -1) break;
				if (key == 27) goto STOP;

				std::cout << "key " << key << " pressed" << std::endl;
			}
		}

		// updates
		cv::scaleAdd(absdiff - deviation, alpha_dev, deviation, deviation);

		cv::scaleAdd(diff, alpha_avg, average, average);

		if (statsched < hrtimer())
		{
			statsched += dstat;

			dcount = frameno - lastcount;
			lastcount = frameno;
			encode_fps = encode_alpha * dcount + (1 - encode_alpha) * encode_fps;

			double timeleft = (nframes - frameno) / encode_fps;

			std::cout << "frame " << frameno;
			std::cout << ", " << std::fixed << std::setprecision(2) << encode_fps << " fps";
			std::cout << ", " << std::fixed << std::setprecision(3) << (100. * frameno / nframes) << "%";
			std::cout << ", ETA " << std::fixed << std::setprecision(2) << (timeleft / 60) << "min  \r";
			std::cout.flush();
		}

	}
STOP:

	running = false;
	WriteElement const tmp = { true };
	writequeue.push(tmp);

	std::cout << std::endl << "done" << std::endl;

	if (reader.joinable())
		reader.join();

	if (writer.joinable())
		writer.join();

	vid->release();
	delete vid;

	//odiff.release();
	//omask.release();
	//oaudio.close();


	return 0;
}
예제 #22
0
void readfn(cv::VideoCapture *vid)
{
	int frameno = (int)vid->get(CV_CAP_PROP_POS_FRAMES);
	int const width = (int)vid->get(CV_CAP_PROP_FRAME_WIDTH);
	int const height = (int)vid->get(CV_CAP_PROP_FRAME_HEIGHT);

	cv::Mat blendedframe, curframe;
	cv::Mat floatframe;
	cv::Mat grayframe;

	blendedframe.create(cv::Size(width, height), CV_16UC3);

	while (running)
	{
		if (!vid->grab())
			break;

		bool do_process = true;

		if (blendframes)
		{
			vid->retrieve(curframe);
			//curframe.convertTo(curframe, CV_16UC3);

			/*
			std::ostringstream label;
			label << "Frame " << frameno;
			cv::putText(curframe, label.str(), cv::Point(10, 20 * (frameno % 50)), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar::all(255), 2);
			//*/

			//std::cerr << "%reduction = " << (frameno % reduction) << std::endl;

			if (frameno % reduction == 0)
				blendedframe.setTo(0);

			//blendedframe = cv::max(blendedframe, curframe);
			cv::add(blendedframe, curframe, blendedframe, cv::noArray(), CV_16UC3);

			if (frameno % reduction == reduction - 1)
				blendedframe.convertTo(floatframe, CV_32FC3, 1.0 / (reduction * 255));
			else
				do_process = false;



			/*
			cv::Mat foo;
			cv::resize(blendedframe, foo, cv::Size(640, 360));
			cv::imshow("debug", foo);
			if (cv::waitKey(100) != -1) exit(0);
			//*/

			//std::cerr << "do_process = " << (do_process) << std::endl;

		}
		else
		{
			if (frameno % reduction == reduction - 1)
			{
				vid->retrieve(curframe);
				curframe.convertTo(floatframe, CV_32FC3, 1.0 / 255);
			}
			else
			{
				do_process = false;
			}

		}

		frameno += 1;

		if (!do_process)
			continue;

		// TODO: proper bounded queue...
		while (running)
		{
			bool foo;
			bool res = donequeue.try_pop(foo);
			if (res)
				break;
		}

		// frameu8 is ready
		cv::cvtColor(floatframe, grayframe, CV_BGR2GRAY, 1);
		cv::blur(grayframe, grayframe, blur);

		MatOrNothing const tmp = { true, floatframe.clone(), grayframe.clone(), frameno };
		framequeue.push(tmp);
		//std::cout << "pushing frame " << frameno << std::endl;
	}

	MatOrNothing const tmp = { false };
	framequeue.push(tmp);
}
예제 #23
0
파일: main.cpp 프로젝트: CCJY/coliru
 ~concurrent() { q.push([=]{ done=true; }); thd.join(); }