DLLEXPORT int ph_codec_plugin_init(void (*codec_register)(phcodec_t *)) { codec_register(&speexnb_codec); codec_register(&speexwb_codec); return 0; }
DLLEXPORT int ph_codec_plugin_init(void (*codec_register)(phcodec_t *)) { codec_register(&g729_codec); return 0; }
static int ioctl_codec_create(struct drm_device *dev, void *data, struct drm_file *file) { struct dce_file_priv *priv = omap_drm_file_priv(file, dce_mapper_id); struct drm_omap_dce_codec_create *arg = data; struct dce_rpc_codec_create_rsp *rsp; int ret; /* if we are not re-starting a syscall, send req */ if (!arg->token) { struct dce_rpc_codec_create_req req = { .hdr = MKHDR(CODEC_CREATE), .codec_id = arg->codec_id, }; strncpy(req.name, arg->name, sizeof(req.name)); ret = engine_get(priv, arg->eng_handle, &req.engine); if (ret) return ret; ret = PTR_RET(get_paddr(priv, hdr(&req), &req.sparams, arg->sparams_bo)); if (ret) goto rpsend_out; ret = rpsend(priv, &arg->token, hdr(&req), sizeof(req)); rpsend_out: if (ret) return rpabort(hdr(&req), ret); } /* then wait for reply, which is interruptible */ ret = rpwait(priv, arg->token, hdr(&rsp), sizeof(*rsp)); if (ret) return ret; arg->codec_handle = codec_register(priv, rsp->codec, arg->codec_id); if (!codec_valid(priv, arg->codec_handle)) { codec_delete(priv, rsp->codec, arg->codec_id); ret = -ENOMEM; } kfree(rsp); return ret; } static int ioctl_codec_control(struct drm_device *dev, void *data, struct drm_file *file) { struct dce_file_priv *priv = omap_drm_file_priv(file, dce_mapper_id); struct drm_omap_dce_codec_control *arg = data; struct dce_rpc_codec_control_rsp *rsp; int ret; /* if we are not re-starting a syscall, send req */ if (!arg->token) { struct dce_rpc_codec_control_req req = { .hdr = MKHDR(CODEC_CONTROL), .cmd_id = arg->cmd_id, }; ret = codec_get(priv, arg->codec_handle, &req.codec, &req.codec_id); if (ret) return ret; ret = PTR_RET(get_paddr(priv, hdr(&req), &req.dparams, arg->dparams_bo)); if (ret) goto rpsend_out; ret = PTR_RET(get_paddr(priv, hdr(&req), &req.status, arg->status_bo)); if (ret) goto rpsend_out; ret = rpsend(priv, &arg->token, hdr(&req), sizeof(req)); rpsend_out: if (ret) return rpabort(hdr(&req), ret); } /* then wait for reply, which is interruptible */ ret = rpwait(priv, arg->token, hdr(&rsp), sizeof(*rsp)); if (ret) return ret; arg->result = rsp->result; kfree(rsp); return 0; } struct viddec3_in_args { int32_t size; /* struct size */ int32_t num_bytes; int32_t input_id; }; struct videnc2_in_args { int32_t size; int32_t input_id; int32_t control; }; union xdm2_buf_size { struct { int32_t width; int32_t height; } tiled; int32_t bytes; }; struct xdm2_single_buf_desc { uint32_t buf; int16_t mem_type; /* XXX should be XDM_MEMTYPE_BO */ int16_t usage_mode; union xdm2_buf_size buf_size; int32_t accessMask; }; struct xdm2_buf_desc { int32_t num_bufs; struct xdm2_single_buf_desc descs[16]; }; struct video2_buf_desc { int32_t num_planes; int32_t num_meta_planes; int32_t data_layout; struct xdm2_single_buf_desc plane_desc[3]; struct xdm2_single_buf_desc metadata_plane_desc[3]; /* rest of the struct isn't interesting to kernel.. if you are * curious look at IVIDEO2_BufDesc in ivideo.h in codec-engine */ uint32_t data[30]; }; #define XDM_MEMTYPE_RAW 0 #define XDM_MEMTYPE_TILED8 1 #define XDM_MEMTYPE_TILED16 2 #define XDM_MEMTYPE_TILED32 3 #define XDM_MEMTYPE_TILEDPAGE 4 /* copy_from_user helper that also checks to avoid overrunning * the 'to' buffer and advances dst ptr */ static inline int cfu(void **top, uint64_t from, int n, void *end) { void *to = *top; int ret; if ((to + n) >= end) { DBG("dst buffer overflow!"); return -EFAULT; } ret = copy_from_user(to, (char __user *)(uintptr_t)from, n); *top = to + n; return ret; } static inline struct drm_gem_object * handle_single_buf_desc( struct dce_file_priv *priv, struct dce_rpc_hdr *req, uint32_t base_bo, struct xdm2_single_buf_desc *desc) { struct drm_gem_object *obj; uint32_t flags; int32_t offset; /* maybe support remapping user ptrs later on.. */ if (desc->mem_type != XDM_MEMTYPE_BO && desc->mem_type != XDM_MEMTYPE_BO_OFFSET) return ERR_PTR(-EINVAL); if (desc->mem_type == XDM_MEMTYPE_BO_OFFSET) { /* desc->buf is an offset to base_bo, which is descs[0].buf as * passed to _process */ offset = desc->buf; desc->buf = base_bo; } else { offset = -1; } obj = get_paddr(priv, req, &desc->buf, desc->buf); if (IS_ERR(obj)) return obj; if (offset != -1) desc->buf += offset; flags = omap_gem_flags(obj); switch(flags & OMAP_BO_TILED) { case OMAP_BO_TILED_8: desc->mem_type = XDM_MEMTYPE_TILED8; break; case OMAP_BO_TILED_16: desc->mem_type = XDM_MEMTYPE_TILED16; break; case OMAP_BO_TILED_32: desc->mem_type = XDM_MEMTYPE_TILED32; break; default: // XXX this is where it gets a bit messy.. some codecs // might want to see XDM_MEMTYPE_RAW for bitstream buffers desc->mem_type = XDM_MEMTYPE_TILEDPAGE; break; } if (flags & OMAP_BO_TILED) { uint16_t w, h; omap_gem_tiled_size(obj, &w, &h); desc->buf_size.tiled.width = w; desc->buf_size.tiled.height = h; } // XXX not sure if the codecs care about usage_mode.. but we // know if the buffer is cached or not so we could set DATASYNC // bit if needed.. return obj; } static inline int handle_buf_desc(struct dce_file_priv *priv, void **ptr, void *end, struct dce_rpc_hdr *req, uint64_t usr, struct drm_gem_object **o1, struct drm_gem_object **o2, uint8_t *len) { struct xdm2_buf_desc *bufs = *ptr; uint32_t base_bo; int i, ret; /* read num_bufs field: */ ret = cfu(ptr, usr, 4, end); if (ret) return ret; /* read rest of structure: */ ret = cfu(ptr, usr+4, bufs->num_bufs * sizeof(bufs->descs[0]), end); if (ret) return ret; *len = (4 + bufs->num_bufs * sizeof(bufs->descs[0])) / 4; /* the bo used as a base for XDM_MEMTYPE_BO_OFFSET descriptors */ base_bo = bufs->descs[0].buf; /* handle buffer mapping.. */ for (i = 0; i < bufs->num_bufs; i++) { struct drm_gem_object *obj = handle_single_buf_desc(priv, req, base_bo, &bufs->descs[i]); if (IS_ERR(obj)) { return PTR_ERR(obj); } if (i == 0) *o1 = obj; if (o2 && (i == 1)) *o2 = obj; } return 0; } /* * VIDDEC3_process VIDENC2_process * VIDDEC3_InArgs *inArgs VIDENC2_InArgs *inArgs * XDM2_BufDesc *outBufs XDM2_BufDesc *outBufs * XDM2_BufDesc *inBufs VIDEO2_BufDesc *inBufs */ static inline int handle_videnc2(struct dce_file_priv *priv, void **ptr, void *end, int32_t *input_id, struct dce_rpc_codec_process_req *req, struct drm_omap_dce_codec_process *arg) { WARN_ON(1); // XXX not implemented // codec_lockbuf(priv, arg->codec_handle, in_args->input_id, y, uv); return -EFAULT; }