Пример #1
0
DLLEXPORT int ph_codec_plugin_init(void (*codec_register)(phcodec_t *))
{
  codec_register(&speexnb_codec);
  codec_register(&speexwb_codec);

  return 0;
}
Пример #2
0
DLLEXPORT int ph_codec_plugin_init(void (*codec_register)(phcodec_t *))
{
  codec_register(&g729_codec);

  return 0;
}
Пример #3
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;
}