VdpStatus vdp_video_surface_destroy(VdpVideoSurface surface) { video_surface_ctx_t *vs = handle_get(surface); if (!vs) return VDP_STATUS_INVALID_HANDLE; if (vs->decoder_private_free) vs->decoder_private_free(vs); if( cedarv_isValid(vs->dataY) ) cedarv_free(vs->dataY); if( cedarv_isValid(vs->dataU) ) cedarv_free(vs->dataU); if (cedarv_isValid(vs->dataV) ) cedarv_free(vs->dataV); cedarv_setBufferInvalid(vs->dataY); cedarv_setBufferInvalid(vs->dataU); cedarv_setBufferInvalid(vs->dataV); VDPAU_DBG("vdpau video surface=%d destroyed", surface); handle_release(surface); handle_destroy(surface); return VDP_STATUS_OK; }
void handle_free(struct handle *h) { assert(h && !h->u.g.moribund); if (h->u.g.busy && h->type != HT_FOREIGN) { /* * If the handle is currently busy, we cannot immediately free * it, because its subthread is in the middle of something. * (Exception: foreign handles don't have a subthread.) * * Instead we must wait until it's finished its current * operation, because otherwise the subthread will write to * invalid memory after we free its context from under it. So * we set the moribund flag, which will be noticed next time * an operation completes. */ h->u.g.moribund = TRUE; } else if (h->u.g.defunct) { /* * There isn't even a subthread; we can go straight to * handle_destroy. */ handle_destroy(h); } else { /* * The subthread is alive but not busy, so we now signal it * to die. Set the moribund flag to indicate that it will * want destroying after that. */ h->u.g.moribund = TRUE; h->u.g.done = TRUE; h->u.g.busy = TRUE; SetEvent(h->u.g.ev_from_main); } }
VdpStatus vdp_bitmap_surface_create(VdpDevice device, VdpRGBAFormat rgba_format, uint32_t width, uint32_t height, VdpBool frequently_accessed, VdpBitmapSurface *surface) { int ret = VDP_STATUS_OK; if (!surface) return VDP_STATUS_INVALID_POINTER; device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; bitmap_surface_ctx_t *out = handle_create(sizeof(*out), surface); if (!out) return VDP_STATUS_RESOURCES; out->frequently_accessed = frequently_accessed; ret = rgba_create(&out->rgba, dev, width, height, rgba_format); if (ret != VDP_STATUS_OK) { handle_destroy(*surface); return ret; } return VDP_STATUS_OK; }
VdpStatus vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, VdpGetProcAddress **get_proc_address) { if (!display || !device || !get_proc_address) return VDP_STATUS_INVALID_POINTER; device_ctx_t *dev = handle_create(sizeof(*dev), device); if (!dev) return VDP_STATUS_RESOURCES; dev->display = XOpenDisplay(XDisplayString(display)); dev->screen = screen; if (!ve_open()) { handle_destroy(*device); return VDP_STATUS_ERROR; } char *env_vdpau_osd = getenv("VDPAU_OSD"); if (env_vdpau_osd && strncmp(env_vdpau_osd, "1", 1) == 0) { dev->g2d_fd = open("/dev/g2d", O_RDWR); if (dev->g2d_fd != -1) dev->osd_enabled = 1; else VDPAU_DBG("Failed to open /dev/g2d! OSD disabled."); } *get_proc_address = vdp_get_proc_address; return VDP_STATUS_OK; }
int main(int argc, char **argv){ int ret = 0; //check argc if(argc < 2) print_help(-1); if(access("/dev/datto-ctl", F_OK) != 0){ errno = EINVAL; perror("driver does not appear to be loaded"); return -1; } //route to appropriate handler or print help if(!strcmp(argv[1], "setup-snapshot")) ret = handle_setup_snap(argc - 1, argv + 1); else if(!strcmp(argv[1], "reload-snapshot")) ret = handle_reload_snap(argc - 1, argv + 1); else if(!strcmp(argv[1], "reload-incremental")) ret = handle_reload_inc(argc - 1, argv + 1); else if(!strcmp(argv[1], "destroy")) ret = handle_destroy(argc - 1, argv + 1); else if(!strcmp(argv[1], "transition-to-incremental")) ret = handle_transition_inc(argc - 1, argv + 1); else if(!strcmp(argv[1], "transition-to-snapshot")) ret = handle_transition_snap(argc - 1, argv + 1); else if(!strcmp(argv[1], "reconfigure")) ret = handle_reconfigure(argc - 1, argv + 1); else if(!strcmp(argv[1], "help")) print_help(0); else print_help(-1); if(ret) perror("driver returned an error performing specified action. check dmesg for more info"); return ret; }
VdpStatus vdp_presentation_queue_destroy(VdpPresentationQueue presentation_queue) { queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; handle_destroy(presentation_queue); free(q); return VDP_STATUS_OK; }
VdpStatus vdp_output_surface_destroy(VdpOutputSurface surface) { output_surface_ctx_t *out = handle_get(surface); if (!out) return VDP_STATUS_INVALID_HANDLE; handle_destroy(surface); free(out); return VDP_STATUS_OK; }
VdpStatus vdp_video_mixer_destroy(VdpVideoMixer mixer) { mixer_ctx_t *mix = handle_get(mixer); if (!mix) return VDP_STATUS_INVALID_HANDLE; handle_release(mixer); handle_destroy(mixer); return VDP_STATUS_OK; }
VdpStatus vdp_bitmap_surface_destroy(VdpBitmapSurface surface) { bitmap_surface_ctx_t *out = handle_get(surface); if (!out) return VDP_STATUS_INVALID_HANDLE; rgba_destroy(&out->rgba); handle_destroy(surface); return VDP_STATUS_OK; }
VdpStatus vdp_output_surface_destroy(VdpOutputSurface surface) { output_surface_ctx_t *out = handle_get(surface); if (!out) return VDP_STATUS_INVALID_HANDLE; memset(out, 0, sizeof(*out)); handle_release(surface); handle_destroy(surface); return VDP_STATUS_OK; }
VdpStatus vdp_device_destroy(VdpDevice device) { device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; cedarv_close(); //XCloseDisplay(dev->display); handle_release(device); handle_destroy(device); return VDP_STATUS_OK; }
VdpStatus vdp_device_destroy(VdpDevice device) { device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; if (dev->osd_enabled) close(dev->g2d_fd); ve_close(); XCloseDisplay(dev->display); handle_destroy(device); return VDP_STATUS_OK; }
static struct nl_handle *gen_handle(struct nl_cb* cb){ struct nl_handle *handle; uint32_t pid = getpid() & 0x3FFFFF; int i; handle = nl_handle_alloc_cb(cb); for (i = 0; i < 1024; i++) { if (port_bitmap[i / 32] & (1 << (i % 32))) continue; port_bitmap[i / 32] |= 1 << (i % 32); pid += i << 22; break; } nl_socket_set_local_port(handle, pid); if (!handle){ flooder_log(FLOODER_DEBUG, "Failed to allocate a handle"); return handle; } if(genl_connect(handle)){ flooder_log(FLOODER_DEBUG, "Cannot connect to handle"); handle_destroy(handle); return NULL; } if ((handle_id = genl_ctrl_resolve(handle, "nl80211")) < 0){ flooder_log(FLOODER_DEBUG, "Cannot resolve nl80211"); handle_destroy(handle); return NULL; } return handle; }
VdpStatus vdp_decoder_destroy(VdpDecoder decoder) { decoder_ctx_t *dec = handle_get(decoder); if (!dec) return VDP_STATUS_INVALID_HANDLE; if (dec->extra_data) ve_free(dec->extra_data); ve_free(dec->data); handle_destroy(decoder); free(dec); return VDP_STATUS_OK; }
VdpStatus vdp_video_surface_destroy(VdpVideoSurface surface) { video_surface_ctx_t *vs = handle_get(surface); if (!vs) return VDP_STATUS_INVALID_HANDLE; if (vs->extra_data) ve_free(vs->extra_data); ve_free(vs->data); handle_destroy(surface); free(vs); return VDP_STATUS_OK; }
VdpStatus vdp_video_surface_destroy(VdpVideoSurface surface) { video_surface_ctx_t *vs = handle_get(surface); if (!vs) return VDP_STATUS_INVALID_HANDLE; if (vs->decoder_private_free) vs->decoder_private_free(vs); yuv_unref(vs->yuv); handle_destroy(surface); return VDP_STATUS_OK; }
VdpStatus vdp_output_surface_destroy(VdpOutputSurface surface) { output_surface_ctx_t *out = handle_get(surface); if (!out) return VDP_STATUS_INVALID_HANDLE; rgba_destroy(&out->rgba); if (out->yuv) yuv_unref(out->yuv); handle_destroy(surface); free(out); return VDP_STATUS_OK; }
VdpStatus vdp_decoder_destroy(VdpDecoder decoder) { VDPAU_DBG("vdpau decoder=%d destroyed", decoder); decoder_ctx_t *dec = handle_get(decoder); if (!dec) return VDP_STATUS_INVALID_HANDLE; if (dec->private_free) dec->private_free(dec); cedarv_free(dec->data); handle_release(decoder); handle_destroy(decoder); return VDP_STATUS_OK; }
void on_accept(struct handle *handle) { int fd; struct handle *client; retry: fd = accept(handle->fd, NULL, 0); if (fd == -1) { if (errno == EINTR) { goto retry; } LOG(WARN, "accept() failed:%s", strerror(errno)); handle_destroy(handle); return; } LOG(INFO, "client connected"); client = handle_create(fd); client->readcb = on_http_read; client->arg = calloc(1, sizeof(struct http_arg)); client->deleter = http_arg_deleter; }
VdpStatus vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, VdpGetProcAddress **get_proc_address) { if (!device || !get_proc_address) { VDPAU_DBG_ONCE("device=NULL || get_proc_address"); return VDP_STATUS_INVALID_POINTER; } device_ctx_t *dev = handle_create(sizeof(*dev), device, htype_device); if (!dev) return VDP_STATUS_RESOURCES; //dev->display = XOpenDisplay(XDisplayString(display)); dev->screen = screen; dev->fb_id = 0; if (!cedarv_open()) { VDPAU_DBG_ONCE("cedarv_open failed"); handle_destroy(*device); return VDP_STATUS_ERROR; } char *env_vdpau_osd = getenv("VDPAU_OSD"); if (env_vdpau_osd && strncmp(env_vdpau_osd, "1", 1) == 0) { dev->g2d_fd = open("/dev/g2d", O_RDWR); if (dev->g2d_fd != -1) dev->osd_enabled = 1; else VDPAU_DBG("Failed to open /dev/g2d! OSD disabled."); } VDPAU_DBG("VE version 0x%04x opened", cedarv_get_version()); *get_proc_address = &vdp_get_proc_address; return VDP_STATUS_OK; }
VdpStatus vdp_presentation_queue_target_destroy(VdpPresentationQueueTarget presentation_queue_target) { queue_target_ctx_t *qt = handle_get(presentation_queue_target); if (!qt) return VDP_STATUS_INVALID_HANDLE; uint32_t args[4] = { 0, qt->layer, 0, 0 }; ioctl(qt->fd, DISP_CMD_LAYER_CLOSE, args); ioctl(qt->fd, DISP_CMD_LAYER_RELEASE, args); if (qt->layer_top) { args[1] = qt->layer_top; ioctl(qt->fd, DISP_CMD_LAYER_CLOSE, args); ioctl(qt->fd, DISP_CMD_LAYER_RELEASE, args); } close(qt->fd); handle_destroy(presentation_queue_target); free(qt); return VDP_STATUS_OK; }
VdpStatus vdp_video_surface_create(VdpDevice device, VdpChromaType chroma_type, uint32_t width, uint32_t height, VdpVideoSurface *surface) { if (!surface) return VDP_STATUS_INVALID_POINTER; if (width < 1 || width > 8192 || height < 1 || height > 8192) return VDP_STATUS_INVALID_SIZE; device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; video_surface_ctx_t *vs = handle_create(sizeof(*vs), surface); if (!vs) return VDP_STATUS_RESOURCES; vs->device = dev; vs->width = width; vs->height = height; vs->chroma_type = chroma_type; vs->luma_size = ALIGN(width, 32) * ALIGN(height, 32); VdpStatus ret = yuv_new(vs); if (ret != VDP_STATUS_OK) { handle_destroy(*surface); return ret; } return VDP_STATUS_OK; }
void handle_got_event(HANDLE event) { struct handle *h; assert(handles_by_evtomain); h = find234(handles_by_evtomain, &event, handle_find_evtomain); if (!h) { /* * This isn't an error condition. If two or more event * objects were signalled during the same select operation, * and processing of the first caused the second handle to * be closed, then it will sometimes happen that we receive * an event notification here for a handle which is already * deceased. In that situation we simply do nothing. */ return; } if (h->u.g.moribund) { /* * A moribund handle is already treated as dead from the * external user's point of view, so do nothing with the * actual event. Just signal the thread to die if * necessary, or destroy the handle if not. */ if (h->u.g.done) { handle_destroy(h); } else { h->u.g.done = TRUE; h->u.g.busy = TRUE; SetEvent(h->u.g.ev_from_main); } return; } if (!h->output) { int backlog; h->u.i.busy = FALSE; /* * A signal on an input handle means data has arrived. */ if (h->u.i.len == 0) { /* * EOF, or (nearly equivalently) read error. */ h->u.i.gotdata(h, NULL, -h->u.i.readerr); h->u.i.defunct = TRUE; } else { backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len); handle_throttle(&h->u.i, backlog); } } else { h->u.o.busy = FALSE; /* * A signal on an output handle means we have completed a * write. Call the callback to indicate that the output * buffer size has decreased, or to indicate an error. */ if (h->u.o.writeerr) { /* * Write error. Send a negative value to the callback, * and mark the thread as defunct (because the output * thread is terminating by now). */ h->u.o.sentdata(h, -h->u.o.writeerr); h->u.o.defunct = TRUE; } else { bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten); h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data)); handle_try_output(&h->u.o); } } }
void handle_got_event(HANDLE event) #endif { struct handle *h; assert(handles_by_evtomain); h = find234(handles_by_evtomain, &event, handle_find_evtomain); if (!h) { /* * This isn't an error condition. If two or more event * objects were signalled during the same select operation, * and processing of the first caused the second handle to * be closed, then it will sometimes happen that we receive * an event notification here for a handle which is already * deceased. In that situation we simply do nothing. */ #ifdef MPEXT return 0; #else return; #endif } if (h->u.g.moribund) { /* * A moribund handle is one which we have either already * signalled to die, or are waiting until its current I/O op * completes to do so. Either way, it's treated as already * dead from the external user's point of view, so we ignore * the actual I/O result. We just signal the thread to die if * we haven't yet done so, or destroy the handle if not. */ if (h->u.g.done) { handle_destroy(h); } else { h->u.g.done = TRUE; h->u.g.busy = TRUE; SetEvent(h->u.g.ev_from_main); } #ifdef MPEXT return 0; #else return; #endif } switch (h->type) { int backlog; case HT_INPUT: h->u.i.busy = FALSE; /* * A signal on an input handle means data has arrived. */ if (h->u.i.len == 0) { /* * EOF, or (nearly equivalently) read error. */ h->u.i.defunct = TRUE; h->u.i.gotdata(h, NULL, -h->u.i.readerr); } else { backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len); handle_throttle(&h->u.i, backlog); } #ifdef MPEXT return 1; #else break; #endif case HT_OUTPUT: h->u.o.busy = FALSE; /* * A signal on an output handle means we have completed a * write. Call the callback to indicate that the output * buffer size has decreased, or to indicate an error. */ if (h->u.o.writeerr) { /* * Write error. Send a negative value to the callback, * and mark the thread as defunct (because the output * thread is terminating by now). */ h->u.o.defunct = TRUE; h->u.o.sentdata(h, -h->u.o.writeerr); } else { bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten); h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data)); handle_try_output(&h->u.o); } #ifdef MPEXT return 0; #else break; #endif case HT_FOREIGN: /* Just call the callback. */ h->u.f.callback(h->u.f.ctx); #ifdef MPEXT return 0; #else break; #endif } #ifdef MPEXT return 0; #endif }
VdpStatus vdp_video_surface_create(VdpDevice device, VdpChromaType chroma_type, uint32_t width, uint32_t height, VdpVideoSurface *surface) { if (!surface) return VDP_STATUS_INVALID_POINTER; if (!width || !height) return VDP_STATUS_INVALID_SIZE; device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; video_surface_ctx_t *vs = handle_create(sizeof(*vs), surface, htype_video); if (!vs) return VDP_STATUS_RESOURCES; VDPAU_DBG("vdpau video surface=%d created", *surface); vs->device = dev; vs->width = width; vs->height = height; vs->chroma_type = chroma_type; vs->stride_width = (width + 63) & ~63; vs->stride_height = (height + 63) & ~63; vs->plane_size = vs->stride_width * vs->stride_height; cedarv_setBufferInvalid(vs->dataY); cedarv_setBufferInvalid(vs->dataU); cedarv_setBufferInvalid(vs->dataV); switch (chroma_type) { case VDP_CHROMA_TYPE_444: //vs->data = cedarv_malloc(vs->plane_size * 3); vs->dataY = cedarv_malloc(vs->plane_size); vs->dataU = cedarv_malloc(vs->plane_size); vs->dataV = cedarv_malloc(vs->plane_size); if (! cedarv_isValid(vs->dataY) || ! cedarv_isValid(vs->dataU) || ! cedarv_isValid(vs->dataV)) { printf("vdpau video surface=%d create, failure\n", *surface); handle_destroy(*surface); handle_release(device); return VDP_STATUS_RESOURCES; } break; case VDP_CHROMA_TYPE_422: //vs->data = cedarv_malloc(vs->plane_size * 2); vs->dataY = cedarv_malloc(vs->plane_size); vs->dataU = cedarv_malloc(vs->plane_size/2); vs->dataV = cedarv_malloc(vs->plane_size/2); if (! cedarv_isValid(vs->dataY) || ! cedarv_isValid(vs->dataU) || ! cedarv_isValid(vs->dataV)) { printf("vdpau video surface=%d create, failure\n", *surface); handle_destroy(*surface); handle_release(device); return VDP_STATUS_RESOURCES; } break; case VDP_CHROMA_TYPE_420: //vs->data = cedarv_malloc(vs->plane_size + (vs->plane_size / 2)); vs->dataY = cedarv_malloc(vs->plane_size); vs->dataU = cedarv_malloc(vs->plane_size/2); if (! cedarv_isValid(vs->dataY) || ! cedarv_isValid(vs->dataU)) { printf("vdpau video surface=%d create, failure\n", *surface); handle_destroy(*surface); handle_release(device); return VDP_STATUS_RESOURCES; } break; default: free(vs); handle_release(device); return VDP_STATUS_INVALID_CHROMA_TYPE; } handle_release(device); return VDP_STATUS_OK; }
int main(int argc, char * argv[]) { int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) { show_help(argc, argv); return 0; } else if (strcmp(argv[i], "-res") == 0) { show_resources(); return 0; } } init_appres(argc, argv); the_bar.realized = 0; if (!get_display_info() || !init_resources() || !create_main_window()) exit (1); set_signals(); XMapWindow(gdi.display, gdi.mainw); set_keybindings(); XEvent evt; while (1) { XNextEvent(gdi.display, &evt); #ifdef DEBUG printf("wid %08X\t%s\n", (int)(evt.xany.window), event_names[evt.type]); fflush(stdout); #endif switch(evt.type){ case KeyPress: handle_key_press(&evt); break; case ReparentNotify: handle_reparent(&evt); break; case MapRequest: /* add a new tab */ handle_maprequest(&evt); break; case DestroyNotify: /* remove a tab */ handle_destroy(&evt); break; case ConfigureNotify: handle_configure_notify(&evt); break; case ConfigureRequest: handle_configure_request(&evt); break; case Expose: if (evt.xexpose.window != gdi.mainw) bar_handle_expose(&(evt.xexpose)); break; case ButtonPress: bar_handle_button(&(evt.xbutton)); break; case PropertyNotify: bar_handle_prop(&evt); break; case MapNotify: if (evt.xmap.window == gdi.mainw) { if (init_stage == 0) { init_stage ++; spawn_xterm(); } } break; case UnmapNotify: if (the_bar.tab_group.tab_count == 0) exit(0); break; case EnterNotify: set_focus(); break; default: break; } XFlush(gdi.display); }; return 0; }
VdpStatus vdp_decoder_create(VdpDevice device, VdpDecoderProfile profile, uint32_t width, uint32_t height, uint32_t max_references, VdpDecoder *decoder) { device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; if (max_references > 16) return VDP_STATUS_ERROR; decoder_ctx_t *dec = handle_create(sizeof(*dec), decoder, htype_decoder); if (!dec) goto err_ctx; VDPAU_DBG("vdpau decoder=%d created", *decoder); memset(dec, 0, sizeof(*dec)); dec->device = dev; dec->profile = profile; dec->width = width; dec->height = height; dec->data = cedarv_malloc(VBV_SIZE); if (! cedarv_isValid(dec->data)) goto err_data; dec->data_pos = 0; VdpStatus ret; switch (profile) { case VDP_DECODER_PROFILE_MPEG1: case VDP_DECODER_PROFILE_MPEG2_SIMPLE: case VDP_DECODER_PROFILE_MPEG2_MAIN: ret = new_decoder_mpeg12(dec); break; case VDP_DECODER_PROFILE_H264_BASELINE: case VDP_DECODER_PROFILE_H264_MAIN: case VDP_DECODER_PROFILE_H264_HIGH: ret = new_decoder_h264(dec); break; case VDP_DECODER_PROFILE_MPEG4_PART2_SP: case VDP_DECODER_PROFILE_MPEG4_PART2_ASP: case VDP_DECODER_PROFILE_DIVX4_QMOBILE: case VDP_DECODER_PROFILE_DIVX4_MOBILE: case VDP_DECODER_PROFILE_DIVX4_HOME_THEATER: case VDP_DECODER_PROFILE_DIVX4_HD_1080P: case VDP_DECODER_PROFILE_DIVX5_QMOBILE: case VDP_DECODER_PROFILE_DIVX5_MOBILE: case VDP_DECODER_PROFILE_DIVX5_HOME_THEATER: case VDP_DECODER_PROFILE_DIVX5_HD_1080P: ret = new_decoder_mpeg4(dec); break; case VDP_DECODER_PROFILE_DIVX3_HD_1080P: case VDP_DECODER_PROFILE_DIVX3_QMOBILE: case VDP_DECODER_PROFILE_DIVX3_MOBILE: case VDP_DECODER_PROFILE_DIVX3_HOME_THEATER: ret = new_decoder_msmpeg4(dec); break; default: ret = VDP_STATUS_INVALID_DECODER_PROFILE; break; } if (ret != VDP_STATUS_OK) goto err_decoder; handle_release(device); return VDP_STATUS_OK; err_handle: if (dec->private_free) dec->private_free(dec); err_decoder: cedarv_free(dec->data); err_data: handle_destroy(*decoder); err_ctx: handle_release(device); return VDP_STATUS_RESOURCES; }