int BrowserManager::Impl::CreateBrowser( const BrowserSettings &browserSettings, const std::shared_ptr<BrowserListener> &browserListener) { int browserIdentifier = 0; os_event_t *createdEvent; os_event_init(&createdEvent, OS_EVENT_TYPE_AUTO); CefPostTask(TID_UI, BrowserTask::newTask( [&] { CefRefPtr<BrowserRenderHandler> renderHandler( new BrowserRenderHandler(browserSettings.width, browserSettings.height, browserListener)); CefRefPtr<BrowserLoadHandler> loadHandler( new BrowserLoadHandler(browserSettings.css)); CefRefPtr<BrowserClient> browserClient( new BrowserClient(renderHandler,loadHandler)); CefWindowInfo windowInfo; windowInfo.transparent_painting_enabled = true; windowInfo.width = browserSettings.width; windowInfo.height = browserSettings.height; windowInfo.windowless_rendering_enabled = true; CefBrowserSettings cefBrowserSettings; cefBrowserSettings.windowless_frame_rate = browserSettings.fps; CefRefPtr<CefBrowser> browser = CefBrowserHost::CreateBrowserSync(windowInfo, browserClient, browserSettings.url, cefBrowserSettings, nullptr); if (browser != nullptr) { browserIdentifier = browser->GetIdentifier(); browserMap[browserIdentifier] = browser; } os_event_signal(createdEvent); })); os_event_wait(createdEvent); os_event_destroy(createdEvent); return browserIdentifier; }
void video_output_stop(video_t video) { void *thread_ret; if (!video) return; if (video->initialized) { os_event_signal(video->stop_event); pthread_join(video->thread, &thread_ret); os_event_signal(video->update_event); } }
static void rtmp_stream_destroy(void *data) { struct rtmp_stream *stream = data; if (stopping(stream) && !connecting(stream)) { pthread_join(stream->send_thread, NULL); } else if (connecting(stream) || active(stream)) { if (stream->connecting) pthread_join(stream->connect_thread, NULL); os_event_signal(stream->stop_event); if (active(stream)) { os_sem_post(stream->send_sem); obs_output_end_data_capture(stream->output); pthread_join(stream->send_thread, NULL); } } if (stream) { free_packets(stream); dstr_free(&stream->path); dstr_free(&stream->key); dstr_free(&stream->username); dstr_free(&stream->password); dstr_free(&stream->encoder_name); os_event_destroy(stream->stop_event); os_sem_destroy(stream->send_sem); pthread_mutex_destroy(&stream->packets_mutex); circlebuf_free(&stream->packets); bfree(stream); } }
void audio_output_close(audio_t audio) { void *thread_ret; struct audio_line *line; if (!audio) return; if (audio->initialized) { os_event_signal(audio->stop_event); pthread_join(audio->thread, &thread_ret); } line = audio->first_line; while (line) { struct audio_line *next = line->next; audio_line_destroy_data(line); line = next; } for (size_t i = 0; i < audio->inputs.num; i++) audio_input_free(audio->inputs.array+i); for (size_t i = 0; i < MAX_AV_PLANES; i++) da_free(audio->mix_buffers[i]); da_free(audio->inputs); os_event_destroy(audio->stop_event); pthread_mutex_destroy(&audio->line_mutex); bfree(audio); }
static int socket_queue_data(RTMPSockBuf *sb, const char *data, int len, void *arg) { struct rtmp_stream *stream = arg; retry_send: if (!RTMP_IsConnected(&stream->rtmp)) return 0; pthread_mutex_lock(&stream->write_buf_mutex); if (stream->write_buf_len + len > stream->write_buf_size) { pthread_mutex_unlock(&stream->write_buf_mutex); if (os_event_wait(stream->buffer_space_available_event)) { return 0; } goto retry_send; } memcpy(stream->write_buf + stream->write_buf_len, data, len); stream->write_buf_len += len; pthread_mutex_unlock(&stream->write_buf_mutex); os_event_signal (stream->buffer_has_data_event); return len; }
static void *video_thread(void *param) { struct video_output *video = param; uint64_t cur_time = os_gettime_ns(); while (os_event_try(video->stop_event) == EAGAIN) { /* wait half a frame, update frame */ cur_time += (video->frame_time/2); os_sleepto_ns(cur_time); video->cur_video_time = cur_time; os_event_signal(video->update_event); /* wait another half a frame, swap and output frames */ cur_time += (video->frame_time/2); os_sleepto_ns(cur_time); pthread_mutex_lock(&video->data_mutex); video_swapframes(video); video_output_cur_frame(video); pthread_mutex_unlock(&video->data_mutex); } return NULL; }
static void fatal_sock_shutdown(struct rtmp_stream *stream) { closesocket(stream->rtmp.m_sb.sb_socket); stream->rtmp.m_sb.sb_socket = -1; stream->write_buf_len = 0; os_event_signal(stream->buffer_space_available_event); }
void BrowserManager::Impl::PushEvent(std::function<void()> event) { pthread_mutex_lock(&dispatchLock); queue.push_back(event); pthread_mutex_unlock(&dispatchLock); os_event_signal(dispatchEvent); }
void VchiMphiBulkWriteCallback( void * Context ) { VCHIQ_STATE_T * Vchi = (VCHIQ_STATE_T *) Context; #ifdef TRACE_WRITE printk( KERN_ERR "%s: Done\n", __PRETTY_FUNCTION__ ); #endif ++Vchi->bulk.tx.remove; os_event_signal( &Vchi->trigger ); }
void obs_output_stop(obs_output_t output) { if (output) { os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) pthread_join(output->reconnect_thread, NULL); output->info.stop(output->context.data); signal_stop(output, OBS_OUTPUT_SUCCESS); } }
void VchiMphiControlWriteCallback( void * Context ) { VCHIQ_STATE_T * Vchi = (VCHIQ_STATE_T *) Context; #ifdef TRACE_WRITE VCHIQ_TASK_T * Task = &Vchi->ctrl.tx.tasks[Vchi->ctrl.tx.remove & VCHIQ_NUM_TX_TASKS - 1]; printk( KERN_ERR "%s: Completing write @ %u, %p +%4x\n", __PRETTY_FUNCTION__, Vchi->ctrl.tx.remove, Task->data, (uint_t) Task->size ); #endif ++Vchi->ctrl.tx.remove; os_event_signal( &Vchi->trigger ); }
void obs_output_actual_stop(obs_output_t *output, bool force, uint64_t ts) { bool call_stop = true; bool was_reconnecting = false; if (stopping(output)) return; os_event_reset(output->stopping_event); was_reconnecting = reconnecting(output) && !delay_active(output); if (reconnecting(output)) { os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) pthread_join(output->reconnect_thread, NULL); } if (force) { if (delay_active(output)) { call_stop = delay_capturing(output); os_atomic_set_bool(&output->delay_active, false); os_atomic_set_bool(&output->delay_capturing, false); output->stop_code = OBS_OUTPUT_SUCCESS; obs_output_end_data_capture(output); os_event_signal(output->stopping_event); } else { call_stop = data_active(output); } } else { call_stop = data_active(output); } if (output->context.data && call_stop) { output->info.stop(output->context.data, ts); } else if (was_reconnecting) { output->stop_code = OBS_OUTPUT_SUCCESS; signal_stop(output); os_event_signal(output->stopping_event); } }
static void obs_output_end_data_capture_internal(obs_output_t *output, bool signal) { int ret; if (!obs_output_valid(output, "obs_output_end_data_capture")) return; if (!active(output) || !data_active(output)) { if (signal) { signal_stop(output); output->stop_code = OBS_OUTPUT_SUCCESS; } return; } if (delay_active(output)) { os_atomic_set_bool(&output->delay_capturing, false); if (!os_atomic_load_long(&output->delay_restart_refs)) { os_atomic_set_bool(&output->delay_active, false); } else { os_event_signal(output->stopping_event); return; } } os_atomic_set_bool(&output->data_active, false); if (output->video) log_frame_info(output); if (data_capture_ending(output)) pthread_join(output->end_data_capture_thread, NULL); os_atomic_set_bool(&output->end_data_capture_thread_active, true); ret = pthread_create(&output->end_data_capture_thread, NULL, end_data_capture_thread, output); if (ret != 0) { blog(LOG_WARNING, "Failed to create end_data_capture_thread " "for output '%s'!", output->context.name); end_data_capture_thread(output); } if (signal) { signal_stop(output); output->stop_code = OBS_OUTPUT_SUCCESS; } }
static void sinewave_destroy(void *data) { struct sinewave_data *swd = data; if (swd) { if (swd->initialized_thread) { void *ret; os_event_signal(swd->event); pthread_join(swd->thread, &ret); } os_event_destroy(swd->event); bfree(swd); } }
static void v4l2_terminate(struct v4l2_data *data) { if (data->thread) { os_event_signal(data->event); pthread_join(data->thread, NULL); os_event_destroy(data->event); data->thread = 0; } v4l2_destroy_mmap(&data->buffers); if (data->dev != -1) { v4l2_close(data->dev); data->dev = -1; } }
void obs_output_stop(obs_output_t *output) { if (output) { output->stopped = true; os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) pthread_join(output->reconnect_thread, NULL); output->info.stop(output->context.data); signal_stop(output, OBS_OUTPUT_SUCCESS); if (output->video) log_frame_info(output); } }
static void rtmp_stream_destroy(void *data) { struct rtmp_stream *stream = data; if (stopping(stream) && !connecting(stream)) { pthread_join(stream->send_thread, NULL); } else if (connecting(stream) || active(stream)) { if (stream->connecting) pthread_join(stream->connect_thread, NULL); stream->stop_ts = 0; os_event_signal(stream->stop_event); if (active(stream)) { os_sem_post(stream->send_sem); obs_output_end_data_capture(stream->output); pthread_join(stream->send_thread, NULL); } } free_packets(stream); dstr_free(&stream->path); dstr_free(&stream->key); dstr_free(&stream->username); dstr_free(&stream->password); dstr_free(&stream->encoder_name); dstr_free(&stream->bind_ip); os_event_destroy(stream->stop_event); os_sem_destroy(stream->send_sem); pthread_mutex_destroy(&stream->packets_mutex); circlebuf_free(&stream->packets); #ifdef TEST_FRAMEDROPS circlebuf_free(&stream->droptest_info); #endif os_event_destroy(stream->buffer_space_available_event); os_event_destroy(stream->buffer_has_data_event); os_event_destroy(stream->socket_available_event); os_event_destroy(stream->send_thread_signaled_exit); pthread_mutex_destroy(&stream->write_buf_mutex); if (stream->write_buf) bfree(stream->write_buf); bfree(stream); }
static void rtmp_stream_stop(void *data) { struct rtmp_stream *stream = data; if (stopping(stream)) return; if (connecting(stream)) pthread_join(stream->connect_thread, NULL); os_event_signal(stream->stop_event); if (active(stream)) { os_sem_post(stream->send_sem); obs_output_end_data_capture(stream->output); } }
void BrowserManager::Impl::DestroyBrowser(int browserIdentifier) { if (browserMap.count(browserIdentifier) > 0) { CefRefPtr<CefBrowser> browser = browserMap[browserIdentifier]; os_event_t *closeEvent; os_event_init(&closeEvent, OS_EVENT_TYPE_AUTO); CefPostTask(TID_UI, BrowserTask::newTask([&, browser] { browser->GetHost()->CloseBrowser(true); os_event_signal(closeEvent); })); os_event_wait(closeEvent); os_event_destroy(closeEvent); browserMap.erase(browserIdentifier); } }
static void rtmp_stream_stop(void *data, uint64_t ts) { struct rtmp_stream *stream = data; if (stopping(stream)) return; if (connecting(stream)) pthread_join(stream->connect_thread, NULL); stream->stop_ts = ts / 1000ULL; os_event_signal(stream->stop_event); if (active(stream)) { if (stream->stop_ts == 0) os_sem_post(stream->send_sem); } }
static void *end_data_capture_thread(void *data) { bool encoded, has_video, has_audio, has_service; encoded_callback_t encoded_callback; obs_output_t *output = data; convert_flags(output, 0, &encoded, &has_video, &has_audio, &has_service); if (encoded) { if (output->active_delay_ns) encoded_callback = process_delay; else encoded_callback = (has_video && has_audio) ? interleave_packets : default_encoded_callback; if (has_video) obs_encoder_stop(output->video_encoder, encoded_callback, output); if (has_audio) stop_audio_encoders(output, encoded_callback); } else { if (has_video) video_output_disconnect(output->video, default_raw_video_callback, output); if (has_audio) audio_output_disconnect(output->audio, output->mixer_idx, default_raw_audio_callback, output); } if (has_service) obs_service_deactivate(output->service, false); if (output->active_delay_ns) obs_output_cleanup_delay(output); do_output_signal(output, "deactivate"); os_atomic_set_bool(&output->active, false); os_event_signal(output->stopping_event); os_atomic_set_bool(&output->end_data_capture_thread_active, false); return NULL; }
void BrowserManager::Impl::Shutdown() { os_event_t *shutdown_event; os_event_init(&shutdown_event, OS_EVENT_TYPE_AUTO); // post the task CefPostTask(TID_UI, BrowserTask::newTask([] { CefQuitMessageLoop(); })); // this event will then get processed and shut down the dispatcher loop PushEvent([this, shutdown_event] { threadAlive = false; os_event_signal(shutdown_event); }); os_event_wait(shutdown_event); os_event_destroy(shutdown_event); return; }
irqreturn_t vc_gpioirq(int irq, void *devId) { mphi_driver_t* mphidrv; m_irq_slot.ctrl = 0; //data m_irq_slot.len = timer_get_tick_count(); mphidrv = (mphi_driver_t*) devId; assert(mphidrv); if(vchost_gpioirq_handle(irq, devId)) { os_event_signal(&mphidrv->rxtxavail, 0); } else { // VC_DEBUG(Trace, "vc_gpioirq: ignoring gpio irq\n"); } return IRQ_HANDLED; }
void VchiMphiControlReadCallback( void * Context, uint_t Offset, uint_t Bytes ) { VCHIQ_STATE_T * Vchi = (VCHIQ_STATE_T *) Context; #ifdef TRACE_READ VCHIQ_SLOT_T * Slot = &Vchi->ctrl.rx.slots[ Vchi->ctrl.rx.remove.s.slot & VCHIQ_NUM_RX_SLOTS - 1 ]; printk( KERN_ERR "%s: Done receive of %4x bytes @ offset %4x (to %08x, mark %4x)\n", __PRETTY_FUNCTION__, Bytes, Offset, Slot == 0 ? 0 : (char *) Slot->data + Offset, (int) Vchi->ctrl.rx.remove.s.mark ); #endif if (Vchi->ctrl.rx.remove.s.mark + Bytes > VCHIQ_SLOT_SIZE) { ASSERT_EQ( Offset, 0 ); remove_rx_slot( Vchi, Bytes ); } else { ASSERT_EQ( Offset, Vchi->ctrl.rx.remove.s.mark ); Vchi->ctrl.rx.remove.s.mark += Bytes; } os_event_signal( &Vchi->trigger ); }
/* * Destroy the plugin object and free all memory */ static void pulse_destroy(void *vptr) { PULSE_DATA(vptr); if (!data) return; if (data->thread) { void *ret; os_event_signal(data->event); pthread_join(data->thread, &ret); } os_event_destroy(data->event); pa_proplist_free(data->props); blog(LOG_DEBUG, "pulse-input: Input destroyed"); bfree(data); }
static void rtmp_stream_stop(void *data) { struct rtmp_stream *stream = data; void *ret; os_event_signal(stream->stop_event); if (stream->connecting) pthread_join(stream->connect_thread, &ret); if (stream->active) { obs_output_end_data_capture(stream->output); os_sem_post(stream->send_sem); pthread_join(stream->send_thread, &ret); RTMP_Close(&stream->rtmp); } os_event_reset(stream->stop_event); stream->sent_headers = false; }
void obs_output_actual_stop(obs_output_t *output, bool force) { output->stopped = true; os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) pthread_join(output->reconnect_thread, NULL); if (output->context.data) output->info.stop(output->context.data); if (output->video) log_frame_info(output); if (output->delay_active && (force || !output->delay_restart_refs)) { output->delay_active = false; obs_output_end_data_capture(output); } if (force || !output->delay_active) signal_stop(output, OBS_OUTPUT_SUCCESS); }
void BrowserManager::Impl::ExecuteOnBrowser(int browserIdentifier, std::function<void(CefRefPtr<CefBrowser>)> f, bool async) { if (browserMap.count(browserIdentifier) > 0) { CefRefPtr<CefBrowser> browser = browserMap[browserIdentifier]; if (async) { CefPostTask(TID_UI, BrowserTask::newTask([&] { f(browser); })); } else { os_event_t *finishedEvent; os_event_init(&finishedEvent, OS_EVENT_TYPE_AUTO); CefPostTask(TID_UI, BrowserTask::newTask([&] { f(browser); os_event_signal(finishedEvent); })); os_event_wait(finishedEvent); os_event_destroy(finishedEvent); } } }
static void rtmp_stream_stop(void *data, uint64_t ts) { struct rtmp_stream *stream = data; if (stopping(stream) && ts != 0) return; if (connecting(stream)) pthread_join(stream->connect_thread, NULL); stream->stop_ts = ts / 1000ULL; os_event_signal(stream->stop_event); if (ts) stream->shutdown_timeout_ts = ts + (uint64_t)stream->max_shutdown_time_sec * 1000000000ULL; if (active(stream)) { if (stream->stop_ts == 0) os_sem_post(stream->send_sem); } }
/* ---------------------------------------------------------------------- * queue a message for transmission. the two output channels share a * single fifo. * * if the output fifo is full, this routine returns immediately with * MPHI_ERROR_FIFO_FULL. * * when the message has been fully read from memory, * MPHI_EVENT_OUT_DMA_COMPLETED is generated. note that this does * not mean that the host has read the message; the message is placed * in a message fifo and held until the host responds to its interrupt * and issues the appropriate number of read cycles. * -------------------------------------------------------------------- */ static int32_t mphi_out_queue_message(const DRIVER_HANDLE_T handle, uint8_t control, const void *addr, size_t len, uint8_t slot_id, const MPHI_FLAGS_T flags ) { int ret; MPHI_HANDLE_T *mphi; mphi_slot_t slot; mphi = (MPHI_HANDLE_T *) handle; slot.addr = (uint32_t)addr; slot.len = len; slot.id = slot_id; slot.ctrl = control; slot.pos = 0; slot.flags = flags; if(1) { //mphi_dumpmsg(mphi->drv, "TQ", &slot); m_out_slot.ctrl = 0; //data m_out_slot.len = timer_get_tick_count(); } ret = add_slotin((MPHI_HANDLE_T*)handle, &slot); //zrl if (ret==0) { //VC_DEBUG(Trace, "mphi_out_queue_message slot\n"); os_event_signal(&(mphi->drv->rxtxavail), 1); //0 } if(0 != ret) { return MPHI_ERROR_FIFO_FULL; } return 0; }