/// 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; } } }
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; }
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); }
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; }
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; }
/// 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); }
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; }
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; }
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); } } }
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)); }
// 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); }
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 } } }