Beispiel #1
0
Datei: time.c Projekt: SLieng/nvm
/// Sleeps for `us` microseconds.
///
/// @param us          Number of microseconds to sleep.
/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C).
///                    If false, waiting is aborted on any input.
void os_microdelay(uint64_t us, bool ignoreinput)
{
  uint64_t elapsed = 0u;
  uint64_t base = uv_hrtime();
  // Convert microseconds to nanoseconds, or UINT64_MAX on overflow.
  const uint64_t ns = (us < UINT64_MAX / 1000u) ? us * 1000u : UINT64_MAX;

  uv_mutex_lock(&delay_mutex);

  while (elapsed < ns) {
    // If ignoring input, we simply wait the full delay.
    // Else we check for input in ~100ms intervals.
    const uint64_t ns_delta = ignoreinput
                              ? ns - elapsed
                              : MIN(ns - elapsed, 100000000u);  // 100ms

    const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta);
    if (0 != rv && UV_ETIMEDOUT != rv) {
      assert(false);
      break;
    }  // Else: Timeout proceeded normally.

    if (!ignoreinput && os_char_avail()) {
      break;
    }

    const uint64_t now = uv_hrtime();
    elapsed += now - base;
    base = now;
  }

  uv_mutex_unlock(&delay_mutex);
}
static void saturate_threadpool(void) {
  uv_work_t* req;

  ASSERT(0 == uv_cond_init(&signal_cond));
  ASSERT(0 == uv_mutex_init(&signal_mutex));
  ASSERT(0 == uv_mutex_init(&wait_mutex));

  uv_mutex_lock(&signal_mutex);
  uv_mutex_lock(&wait_mutex);

  for (num_threads = 0; /* empty */; num_threads++) {
    req = malloc(sizeof(*req));
    ASSERT(req != NULL);
    ASSERT(0 == uv_queue_work(uv_default_loop(), req, work_cb, done_cb));

    /* Expect to get signalled within 350 ms, otherwise assume that
     * the thread pool is saturated. As with any timing dependent test,
     * this is obviously not ideal.
     */
    if (uv_cond_timedwait(&signal_cond, &signal_mutex, (uint64_t)(350 * 1e6))) {
      ASSERT(0 == uv_cancel((uv_req_t*) req));
      break;
    }
  }
}
Beispiel #3
0
int status_wait(Status* status, uint64_t timeout_secs) {
  int count;
  uv_mutex_lock(&status->mutex);
  uv_cond_timedwait(&status->cond, &status->mutex, timeout_secs * 1000 * 1000 * 1000);
  count = status->count;
  uv_mutex_unlock(&status->mutex);
  return count;
}
Beispiel #4
0
static void microdelay(uint64_t microseconds)
{
  uint64_t hrtime;
  int64_t ns = microseconds * 1000;  // convert to nanoseconds

  uv_mutex_lock(&delay_mutex);

  while (ns > 0) {
    hrtime =  uv_hrtime();
    if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns) == UV_ETIMEDOUT)
      break;
    ns -= uv_hrtime() - hrtime;
  }

  uv_mutex_unlock(&delay_mutex);
}
Beispiel #5
0
static mrb_value
mrb_uv_cond_timed_wait(mrb_state *mrb, mrb_value self)
{
  mrb_value mutex_val;
  mrb_int timeout;
  uv_mutex_t *mutex;
  int err;
  mrb_get_args(mrb, "oi", &mutex_val, &timeout);

  mutex = (uv_mutex_t*)mrb_uv_get_ptr(mrb, mutex_val, &mrb_uv_mutex_type);
  err = uv_cond_timedwait((uv_cond_t*)mrb_uv_get_ptr(mrb, self, &mrb_uv_cond_type), mutex, timeout);
  if (err == UV_ETIMEDOUT) {
    return symbol_value_lit(mrb, "timedout");
  }
  mrb_uv_check_error(mrb, err);
  return self;
}
Beispiel #6
0
static luv_msg_t* luv_queue_recv(luv_queue_t* queue, int timeout)
{
	luv_msg_t* msg = NULL;

	luv_queue_lock(queue);
	if (queue->limit >= 0) {
		queue->limit++;
		uv_cond_signal(&queue->send_sig);
	}

	// wait
	while (timeout != 0 && queue->count <= 0) {
		if (timeout > 0) {
			int64_t waittime = timeout;
			waittime = waittime * 1000000L;
			if (uv_cond_timedwait(&queue->recv_sig, &queue->lock, waittime) != 0) {
				break;
			}

		} else {
			uv_cond_wait(&queue->recv_sig, &queue->lock);
		}
	}

	if (queue->count > 0) {
		msg = queue->msg_head;
		if (msg) {
			queue->msg_head = msg->next;
			if (queue->msg_head == NULL) {
				queue->msg_tail = NULL;
			}
			msg->next = NULL;
		}
		queue->count--;
		uv_cond_signal(&queue->send_sig);
	}

	if (queue->limit > 0) {
		queue->limit--;
	}

	luv_queue_unlock(queue);
	return msg;
}
Beispiel #7
0
/// Sleeps for a certain amount of microseconds
///
/// @param microseconds Number of microseconds to sleep
void os_microdelay(uint64_t microseconds)
{
  uint64_t elapsed = 0;
  uint64_t ns = microseconds * 1000;  // convert to nanoseconds
  uint64_t base = uv_hrtime();

  uv_mutex_lock(&delay_mutex);

  while (elapsed < ns) {
    if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed)
        == UV_ETIMEDOUT)
      break;
    uint64_t now = uv_hrtime();
    elapsed += now - base;
    base = now;
  }

  uv_mutex_unlock(&delay_mutex);
}
Beispiel #8
0
static int luv_queue_send(luv_queue_t* queue, luv_msg_t* msg, int timeout)
{
	luv_queue_lock(queue);

	// wait
	while (timeout != 0 && queue->limit >= 0 && queue->count + 1 > queue->limit) {
		if (timeout > 0) {
			int64_t waittime = timeout;
			waittime = waittime * 1000000L;

			if (uv_cond_timedwait(&queue->send_sig, &queue->lock, waittime) != 0) {
				break;
			}

		} else {
			uv_cond_wait(&queue->send_sig, &queue->lock);
		}
	}

	// printf("queue: %d/%d", queue->limit, queue->count);

	if (queue->limit < 0 || queue->count + 1 <= queue->limit) {
		msg->next = NULL;
		if (queue->msg_tail) {
			queue->msg_tail->next = msg;
		}

		queue->msg_tail = msg;
		if (queue->msg_head == NULL) {
			queue->msg_head = msg;
		}

		queue->count++;
		uv_cond_signal(&queue->recv_sig);

	} else {
		msg = NULL;
	}

	luv_queue_unlock(queue);
	return msg ? 1 : 0;
}
Beispiel #9
0
int CAudioDecoder::fill_iobuffer(uint8_t *buf, int bufsize)
{
	int ret = 0;
	uv_mutex_lock(&queue_mutex);
	if (buf_deque.size() == 0){
		//uv_mutex_unlock(&queue_mutex);
		int ret = uv_cond_timedwait(&queue_not_empty, &queue_mutex, (uint64_t)(1000 * 1e6));
		if (ret == UV_ETIMEDOUT){
			uv_mutex_unlock(&queue_mutex);
			//MessageBox(NULL, TEXT("BUFFER EMPTY!"), TEXT("remote preview"), MB_OK);
			return 1;
		}
	}
	int real_len = 0;
	int buf_rest = bufsize;
	int isize = buf_deque.size();
	for (int i = 0; i < isize; i++){
		cc_src_sample_t s = buf_deque.front();
		if (buf_rest >= s.len){
			memcpy(buf+real_len, s.buf[0], s.len);

			size_t wt = 0;
			if (!fd){
				fd = fopen("test.aac", "wb");
			}
			if (fd) {
				wt = fwrite(s.buf[0], 1, s.len, fd);
			}

			free(s.buf[0]);
			real_len += s.len;
			buf_rest -= s.len;
			buf_deque.pop_front();
		}
		else {
			break;
		}
	}
	uv_mutex_unlock(&queue_mutex);
	return real_len;
}
Beispiel #10
0
void CX264Encoder2::Encode(void)
{
    int ret;
    int gotPic;
    while(!bStop){
        uv_mutex_lock(pQueueMutex);
        if(queueFrame.size() == 0){
            ret = uv_cond_timedwait(pQueueNotEmpty, pQueueMutex, (uint64_t)(500 * 1e6));
            if(ret == UV_ETIMEDOUT){
                uv_mutex_unlock(pQueueMutex);
                MessageBox(NULL, TEXT("BUFFER EMPTY!"), TEXT("remote preview"), MB_OK);
                continue;
            }
        }

        AVFrame* frame = queueFrame.front();
        queueFrame.pop_front();
        uv_mutex_unlock(pQueueMutex);

        /* encode the image */
        AVPacket *pkt = (AVPacket*)av_malloc(sizeof(AVPacket));
        av_init_packet(pkt);
        ret = avcodec_encode_video2(pCodecCtx, pkt, frame, &gotPic);
        if(ret < 0) {
            printf("Error encoding frame\n");
            break;
        }
        if(gotPic) {
            //printf("Succeed to encode frame: %5d\tsize:%5d\n", framecnt, pkt->size);
            //framecnt++;
            //fwrite(pkt->data, 1, pkt->size, fp_out);
            if(m_fnCb){
                m_fnCb(pkt, m_pUserdata);
            }
        } else{
            av_free_packet(pkt);
            av_freep(pkt);
        }
    }
}
Beispiel #11
0
static PyObject *
Condition_func_timedwait(Condition *self, PyObject *args)
{
    int r;
    double timeout;
    Mutex *pymutex;

    RAISE_IF_NOT_INITIALIZED(self, NULL);

    if (!PyArg_ParseTuple(args, "O!d:timedwait", &MutexType, &pymutex, &timeout)) {
        return NULL;
    }

    Py_INCREF(pymutex);

    Py_BEGIN_ALLOW_THREADS
    r = uv_cond_timedwait(&self->uv_condition, &pymutex->uv_mutex, (uint64_t)(timeout*1e9));
    Py_END_ALLOW_THREADS

    Py_DECREF(pymutex);
    return PyBool_FromLong((long)(r == 0));
}
Beispiel #12
0
// the decode work thread
void CVideoDecoder2::Decode(void)
{
    while(!bStop){
        int ret;
        uv_mutex_lock(pQueueMutex);
        if(packetQueue.size() == 0){
            ret = uv_cond_timedwait(pQueueNotEmpty, pQueueMutex, (uint64_t)(1000 * 1e6));
            if(ret == UV_ETIMEDOUT){
                uv_mutex_unlock(pQueueMutex);
                continue;
            }
        }
        AVPacket* pkt = packetQueue.front();
        packetQueue.pop_front();
        uv_mutex_unlock(pQueueMutex);

        if(pkt->data == NULL){ // done, no more packet
            bStop = true;
            av_freep(pkt);
            continue;
        }

        int gotPicture;
        AVFrame* frame = av_frame_alloc();
        if(frame){
            ret = avcodec_decode_video2(pCodecCtx, frame, &gotPicture, pkt);
            if(ret < 0){
                bStop = true;
                av_frame_free(&frame);
                frame = NULL;
                if(fnCallback){
                    fnCallback(frame, ret, pUserData);
                }
                av_free_packet(pkt);
                av_freep(pkt);
                continue;
            }
            if(gotPicture && fnCallback){
                fnCallback(frame, ret, pUserData);
                av_free_packet(pkt);
                av_freep(pkt);
                continue;
            }
        } else{
            bStop = true;
            if(fnCallback){
                fnCallback(frame, ret, pUserData);
            }
            av_free_packet(pkt);
            av_freep(pkt);
            continue;
        }
    }

    // flush
    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;
    int ret;
    do{
        int gotPicture;
        AVFrame* frame = av_frame_alloc();
        if(frame){
            ret = avcodec_decode_video2(pCodecCtx, frame, &gotPicture, &pkt);
            if(ret < 0 || !gotPicture){
                av_frame_free(&frame);
                frame = NULL;
                if(ret == 0){
                    ret = -1;
                }
            }
        } else{
            ret = -1;
        }
        if(fnCallback){
            fnCallback(frame, ret, pUserData);
        }
    } while(ret >= 0);
}
Beispiel #13
0
void CX264Encoder::encode()
{
	//MessageBox(NULL, TEXT("1"), TEXT("remote preview"), MB_OK);
	if (x264_picture_alloc(&pic, param.i_csp, param.i_width, param.i_height) < 0){
		return;
	}
	//MessageBox(NULL, TEXT("2"), TEXT("remote preview"), MB_OK);
	while (!b_stop){
		uv_mutex_lock(&queue_mutex);
		if (sample_queue.size() == 0){
			//uv_mutex_unlock(&queue_mutex);
			int ret = uv_cond_timedwait(&queue_not_empty, &queue_mutex, (uint64_t)(5000 * 1e6));
			if (ret == UV_ETIMEDOUT){
				uv_mutex_unlock(&queue_mutex);
				MessageBox(NULL, TEXT("BUFFER EMPTY!"), TEXT("remote preview"), MB_OK);
				return;
			}
		}

		
		cc_src_sample_t buf = sample_queue.front();
		pic.i_pts = i_frame++;
		int64_t ticks_per_frame = buf.end - buf.start;
		TCHAR m[248];
		swprintf(m, TEXT("len: %d; width: %d; height: %d"), buf.len, param.i_width, param.i_height);
		//MessageBox(NULL, m, TEXT("remote preview"), MB_OK);
		if (param.i_csp == X264_CSP_RGB){
			convert_rgb(pic.img.plane[0], buf.buf[0], param.i_width, param.i_height);
			//memcpy(pic.img.plane[0], buf.buf[0], buf.line[0]*param.i_height);
		}
		else {
			//for (int i = 0; i < buf.iplan; i++){
			//	memcpy(pic.img.plane[i], buf.buf[i], buf.line[i]);
			//}
			memcpy(pic.img.plane[0], buf.buf[0], buf.line[0] * param.i_height);

			memcpy(pic.img.plane[1], buf.buf[1], buf.line[1] * param.i_height / 2);

			memcpy(pic.img.plane[2], buf.buf[2], buf.line[2] * param.i_height / 2);
		}
		//MessageBox(NULL, TEXT("3"), TEXT("remote preview"), MB_OK);
		i_frame_size = x264_encoder_encode(h, &nal, &i_nal, &pic, &pic_out);
		//MessageBox(NULL, TEXT("4"), TEXT("remote preview"), MB_OK);
		if (i_frame_size < 0)
			break;
		else if (i_frame_size)
		{
			//TODO:encode success
			if (fn_cb){
				int i;
				for (i = 0; i < i_nal; i++){
					cc_src_sample_t out_smple;
					out_smple.sync = !!pic_out.b_keyframe;
					out_smple.start = pic_out.i_pts;
					out_smple.end = pic_out.i_pts + ticks_per_frame;
					out_smple.buf[0] = (uint8_t*)malloc(nal[i].i_payload);
					out_smple.len = nal[i].i_payload;
					out_smple.iplan = 1;
					memcpy(out_smple.buf[0], nal[i].p_payload, nal[i].i_payload);
					//MessageBox(NULL, TEXT("5"), TEXT("remote preview"), MB_OK);
					fn_cb(out_smple, p_user_data);
					if (!fd){
						fd = fopen("src.264", "wb");
						if (fd)
							;// MessageBox(NULL, TEXT("create file!"), TEXT("x264 encoder"), MB_OK);
						else
							MessageBox(NULL, TEXT("create file false!"), TEXT("x264 encoder"), MB_OK);
					}
					if (fd){
						fwrite(out_smple.buf[0], 1, out_smple.len, fd);
					}
					free(out_smple.buf[0]);
				}
			}
		}
		//MessageBox(NULL, TEXT("6"), TEXT("remote preview"), MB_OK);
		sample_queue.pop_front();
		for (int i = 0; i < buf.iplan; i++){
			free(buf.buf[i]);
		}
		uv_mutex_unlock(&queue_mutex);
	}

	while (encode_delay()){
		i_frame_size = x264_encoder_encode(h, &nal, &i_nal, NULL, &pic_out);
		if (i_frame_size < 0)
			break;
		else if (i_frame_size)
		{
			//TODO:encode success
		}
	}
}