static void session_destroy(vc_t* vc) { if (vc->fd >= 0) { port_fd_handler_done(&vc->fh); // vc_destroy() closes the fd } if (vc->proc != ZX_HANDLE_INVALID) { zx_task_kill(vc->proc); } vc_destroy(vc); }
int vdpau_codec_create(media_codec_t *mc, enum CodecID id, AVCodecContext *ctx, media_codec_params_t *mcp, media_pipe_t *mp) { VdpDecoderProfile profile; vdpau_dev_t *vd = mp->mp_vdpau_dev; VdpStatus r; int refframes; if(vd == NULL) return 1; if(mcp->width == 0 || mcp->height == 0) return 1; switch(id) { case CODEC_ID_MPEG1VIDEO: profile = VDP_DECODER_PROFILE_MPEG1; mc->codec = avcodec_find_decoder_by_name("mpegvideo_vdpau"); refframes = 2; break; case CODEC_ID_MPEG2VIDEO: profile = VDP_DECODER_PROFILE_MPEG2_MAIN; mc->codec = avcodec_find_decoder_by_name("mpegvideo_vdpau"); refframes = 2; break; case CODEC_ID_H264: profile = VDP_DECODER_PROFILE_H264_HIGH; mc->codec = avcodec_find_decoder_by_name("h264_vdpau"); refframes = 16; break; #if 0 // Seems broken case CODEC_ID_VC1: profile = VDP_DECODER_PROFILE_VC1_ADVANCED; mc->codec = avcodec_find_decoder_by_name("vc1_vdpau"); refframes = 16; break; case CODEC_ID_WMV3: profile = VDP_DECODER_PROFILE_VC1_MAIN; mc->codec = avcodec_find_decoder_by_name("wmv3_vdpau"); refframes = 16; break; #endif default: return 1; } if(mc->codec == NULL) return -1; vdpau_codec_t *vc = calloc(1, sizeof(vdpau_codec_t)); TAILQ_INIT(&vc->vc_vvs_alloc); TAILQ_INIT(&vc->vc_vvs_free); vc->vc_vd = vd; vc->vc_width = mcp->width; vc->vc_height = mcp->height; vc->vc_profile = profile; vc->vc_refframes = refframes; r = vd->vdp_decoder_create(vd->vd_dev, vc->vc_profile, vc->vc_width, vc->vc_height, vc->vc_refframes, &vc->vc_decoder); if(r != VDP_STATUS_OK) { TRACE(TRACE_INFO, "VDPAU", "Unable to create decoder: %s", vdpau_errstr(vd, r)); vc_destroy(vc); return -1; } r = vdpau_create_buffers(vc, vc->vc_width, vc->vc_height, vc->vc_refframes + 5); if(r != VDP_STATUS_OK) { TRACE(TRACE_INFO, "VDPAU", "Unable to allocate decoding buffers"); vc_destroy(vc); return -1; } TRACE(TRACE_DEBUG, "VDPAU", "Decoder initialized"); mc->codec_ctx = ctx ?: avcodec_alloc_context(); mc->codec_ctx->codec_id = mc->codec->id; mc->codec_ctx->codec_type = mc->codec->type; if(avcodec_open(mc->codec_ctx, mc->codec) < 0) { if(ctx == NULL) free(mc->codec_ctx); mc->codec = NULL; vc_destroy(vc); return -1; } mc->codec_ctx->get_buffer = vdpau_get_buffer; mc->codec_ctx->release_buffer = vdpau_release_buffer; mc->codec_ctx->draw_horiz_band = vdpau_draw_horiz_band; mc->codec_ctx->get_format = vdpau_get_pixfmt; mc->codec_ctx->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; mc->codec_ctx->opaque = mc; mc->opaque = vc; mc->decode = vdpau_decode; mc->close = vdpau_codec_close; mc->reinit = vdpau_codec_reinit; return 0; }
static void vdpau_codec_close(struct media_codec *mc) { vdpau_codec_t *vc = mc->opaque; vc_destroy(vc); }
static zx_status_t session_create(vc_t** out, int* out_fd, bool make_active, bool special) { int fd; // The ptmx device can start later than these threads int retry = 30; while ((fd = open("/dev/misc/ptmx", O_RDWR | O_NONBLOCK)) < 0) { if (--retry == 0) { return ZX_ERR_IO; } usleep(100000); } int client_fd = openat(fd, "0", O_RDWR); if (client_fd < 0) { close(fd); return ZX_ERR_IO; } vc_t* vc; if (vc_create(&vc, special)) { close(fd); close(client_fd); return ZX_ERR_INTERNAL; } zx_status_t r; if ((r = port_fd_handler_init(&vc->fh, fd, POLLIN | POLLRDHUP | POLLHUP)) < 0) { vc_destroy(vc); close(fd); close(client_fd); return r; } vc->fd = fd; if (make_active) { vc_set_active(-1, vc); } pty_window_size_t wsz = { .width = vc->columns, .height = vc->rows, }; ioctl_pty_set_window_size(fd, &wsz); vc->fh.func = session_io_cb; *out = vc; *out_fd = client_fd; return ZX_OK; } static void start_shell(bool make_active, const char* cmd) { vc_t* vc; int fd; if (session_create(&vc, &fd, make_active, cmd != NULL) < 0) { return; } vc->is_shell = true; if (launch_shell(vc, fd, cmd) < 0) { session_destroy(vc); } else { port_wait(&port, &vc->fh.ph); } }
static int vdpau_codec_create(media_codec_t *mc, const media_codec_params_t *mcp, media_pipe_t *mp) { VdpDecoderProfile profile; vdpau_dev_t *vd = mp->mp_vdpau_dev; VdpStatus r; int refframes; AVCodec *codec; if(vd == NULL) return 1; if(mcp == NULL || mcp->width == 0 || mcp->height == 0) return 1; switch(mc->codec_id) { case CODEC_ID_MPEG1VIDEO: profile = VDP_DECODER_PROFILE_MPEG1; codec = avcodec_find_decoder_by_name("mpegvideo_vdpau"); refframes = 2; break; case CODEC_ID_MPEG2VIDEO: profile = VDP_DECODER_PROFILE_MPEG2_MAIN; codec = avcodec_find_decoder_by_name("mpegvideo_vdpau"); refframes = 2; break; case CODEC_ID_H264: profile = VDP_DECODER_PROFILE_H264_HIGH; codec = avcodec_find_decoder_by_name("h264_vdpau"); refframes = 16; break; #if 0 // Seems broken case CODEC_ID_VC1: profile = VDP_DECODER_PROFILE_VC1_ADVANCED; mc->codec = avcodec_find_decoder_by_name("vc1_vdpau"); refframes = 16; break; case CODEC_ID_WMV3: profile = VDP_DECODER_PROFILE_VC1_MAIN; mc->codec = avcodec_find_decoder_by_name("wmv3_vdpau"); refframes = 16; break; #endif default: return 1; } if(codec == NULL) return -1; vdpau_codec_t *vc = calloc(1, sizeof(vdpau_codec_t)); TAILQ_INIT(&vc->vc_vvs_alloc); TAILQ_INIT(&vc->vc_vvs_free); vc->vc_vd = vd; vc->vc_width = mcp->width; if(mcp->height == 1088) vc->vc_height = 1080; else vc->vc_height = mcp->height; vc->vc_profile = profile; vc->vc_refframes = refframes; r = vd->vdp_decoder_create(vd->vd_dev, vc->vc_profile, vc->vc_width, vc->vc_height, vc->vc_refframes, &vc->vc_decoder); if(r != VDP_STATUS_OK) { TRACE(TRACE_INFO, "VDPAU", "Unable to create decoder: %s", vdpau_errstr(vd, r)); vc_destroy(vc); return -1; } r = vdpau_create_buffers(vc, vc->vc_width, vc->vc_height, vc->vc_refframes + 5); if(r != VDP_STATUS_OK) { TRACE(TRACE_INFO, "VDPAU", "Unable to allocate decoding buffers"); vc_destroy(vc); return -1; } TRACE(TRACE_DEBUG, "VDPAU", "Decoder initialized"); mc->ctx = avcodec_alloc_context3(codec); if(mcp->extradata != NULL) { mc->ctx->extradata = calloc(1, mcp->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(mc->ctx->extradata, mcp->extradata, mcp->extradata_size); mc->ctx->extradata_size = mcp->extradata_size; } if(avcodec_open2(mc->ctx, codec, NULL) < 0) { free(mc->ctx); vc_destroy(vc); return -1; } mc->ctx->get_buffer = vdpau_get_buffer; mc->ctx->release_buffer = vdpau_release_buffer; mc->ctx->draw_horiz_band = vdpau_draw_horiz_band; mc->ctx->get_format = vdpau_get_pixfmt; mc->ctx->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; mc->ctx->opaque = mc; mc->opaque = vc; mc->decode = vdpau_decode; mc->flush = video_flush_avctx; mc->close = vdpau_codec_close; mc->reinit = vdpau_codec_reinit; return 0; }