static int socksserver_on_clientconnect (void* userdata, struct sockaddr_storage* clientaddr, int fd) { socksserver* srv = (socksserver*) userdata; char buffer[256]; (void) buffer; if(CONFIG_LOG && srv->log && clientaddr) { logstart(); printfd(fd); LOGPUT(1, VARISL(" connect from: "), VARIC(get_client_ip(clientaddr, buffer, sizeof(buffer))), NULL); } if(fd < 3 || fd >= MAX_FD) { rocksockserver_disconnect_client(&srv->serva, fd); return -2; } fdinfo* client = &srv->clients[fdindex(fd)]; // put into nonblocking mode, so that writes will not block the server int flags = fcntl(fd, F_GETFL); if(flags == -1) return -1; if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) return -2; client->data = find_free_buffer(srv); if (!client->data) { if(CONFIG_LOG && srv->log) { logstart(); LOGPUTS(1, SPL("warning: couldnt find free buffer\n")); } rocksockserver_disconnect_client(&srv->serva, fd); return -2; } client->state = SS_CONNECTED; client->data->state = BS_IDLE; client->data->start = 0; client->target_fd = -1; return 0; }
static void request_buffers(struct pp_video_decoder_s *vd) { const PP_Instance instance = vd->instance->id; const struct PP_Size dimensions = { .width = vd->avctx->width, .height = vd->avctx->height }; pp_resource_release(vd->self_id); // TODO: how many surfaces do we need? vd->ppp_video_decoder_dev->ProvidePictureBuffers(instance, vd->self_id, 21, &dimensions, GL_TEXTURE_2D); pp_resource_acquire(vd->self_id, PP_RESOURCE_VIDEO_DECODER); } static uint32_t find_free_buffer(struct pp_video_decoder_s *vd) { for (uint32_t idx = 0; idx < vd->buffer_count; idx ++) { if (!vd->buffers[idx].used) { vd->buffers[idx].used = 1; return idx; } } return (uint32_t)-1; } static void issue_frame(struct pp_video_decoder_s *vd) { AVFrame *frame = vd->avframe; uint32_t idx = find_free_buffer(vd); int32_t bitstream_buffer_id = (int32_t)frame->pkt_pts; if (idx == (uint32_t)-1) { trace_warning("%s, no free buffer available\n", __func__); return; } struct pp_graphics3d_s *g3d = pp_resource_acquire(vd->graphics3d, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, bad resource\n", __func__); return; } VASurfaceID va_surf = GPOINTER_TO_SIZE(frame->data[3]); pthread_mutex_lock(&display.lock); glXMakeCurrent(display.x, g3d->glx_pixmap, g3d->glc); glBindTexture(GL_TEXTURE_2D, vd->buffers[idx].texture_id); display.glXBindTexImageEXT(display.x, vd->buffers[idx].glx_pixmap, GLX_FRONT_EXT, NULL); XFlush(display.x); vaPutSurface(display.va, va_surf, vd->buffers[idx].pixmap, 0, 0, frame->width, frame->height, 0, 0, frame->width, frame->height, NULL, 0, VA_FRAME_PICTURE); XFlush(display.x); glXMakeCurrent(display.x, None, NULL); pthread_mutex_unlock(&display.lock); pp_resource_release(vd->graphics3d); const PP_Instance instance = vd->instance->id; const struct PP_Picture_Dev picture = { .picture_buffer_id = vd->buffers[idx].id, .bitstream_buffer_id = bitstream_buffer_id, }; pp_resource_release(vd->self_id); vd->ppp_video_decoder_dev->PictureReady(instance, vd->self_id, &picture); pp_resource_acquire(vd->self_id, PP_RESOURCE_VIDEO_DECODER); } static void decode_frame(struct pp_video_decoder_s *vd, uint8_t *data, size_t data_len, int32_t bitstream_buffer_id) { AVPacket packet; av_init_packet(&packet); packet.data = data; packet.size = data_len; packet.pts = bitstream_buffer_id; // libavcodec can call hw functions, which in turn can call Xlib functions, // therefore we need to lock pthread_mutex_lock(&display.lock); int got_frame = 0; int len = avcodec_decode_video2(vd->avctx, vd->avframe, &got_frame, &packet); pthread_mutex_unlock(&display.lock); if (len < 0) { trace_error("%s, error %d while decoding frame\n", __func__, len); return; } if (got_frame) { if (!vd->buffers_were_requested) { request_buffers(vd); vd->buffers_were_requested = 1; } issue_frame(vd); } }