blob: 763d62e33e882220ef8d623794a3cecfa829b201
1 | #include <linux/file.h> |
2 | #include <linux/anon_inodes.h> |
3 | #include "vdec_v4l2_buffer_ops.h" |
4 | |
5 | const struct file_operations v4l2_file_fops = {}; |
6 | |
7 | static int is_v4l2_buf_file(struct file *file) |
8 | { |
9 | return file->f_op == &v4l2_file_fops; |
10 | } |
11 | |
12 | static int vdec_v4l_alloc_fd(void) |
13 | { |
14 | int fd; |
15 | struct file *file = NULL; |
16 | |
17 | fd = get_unused_fd_flags(O_CLOEXEC); |
18 | if (fd < 0) { |
19 | pr_err("v4l: get unused fd fail\n"); |
20 | return fd; |
21 | } |
22 | |
23 | file = anon_inode_getfile("v4l2_meta_file", &v4l2_file_fops, NULL, 0); |
24 | if (IS_ERR(file)) { |
25 | put_unused_fd(fd); |
26 | pr_err("v4l: get file faill\n"); |
27 | return PTR_ERR(file); |
28 | } |
29 | |
30 | fd_install(fd, file); |
31 | |
32 | pr_info("v4l: fd %d, file %p, data %p\n", |
33 | fd, file, file->private_data); |
34 | |
35 | return fd; |
36 | } |
37 | |
38 | static int vdec_v4l_fd_install_data(int fd, void *data) |
39 | { |
40 | struct file *file; |
41 | |
42 | file = fget(fd); |
43 | |
44 | if (!file) { |
45 | pr_info("v4l: fget fd %d fail!, comm %s, pid %d\n", |
46 | fd, current->comm, current->pid); |
47 | return -EBADF; |
48 | } |
49 | |
50 | if (!is_v4l2_buf_file(file)) { |
51 | pr_info("v4l: v4l2 check fd fail!\n"); |
52 | return -EBADF; |
53 | } |
54 | |
55 | file->private_data = data; |
56 | |
57 | return 0; |
58 | } |
59 | |
60 | int vdec_v4l_binding_fd_and_vf(ulong v4l_handle, void *vf) |
61 | { |
62 | int ret = 0, fd = -1; |
63 | struct vdec_v4l2_buffer *v4l_buf = |
64 | (struct vdec_v4l2_buffer *) v4l_handle; |
65 | |
66 | if (v4l_buf->m.vf_fd > 0) |
67 | return 0; |
68 | |
69 | fd = vdec_v4l_alloc_fd(); |
70 | if (fd < 0) { |
71 | pr_err("v4l: alloc fd fail %d.\n", fd); |
72 | return fd; |
73 | } |
74 | |
75 | ret = vdec_v4l_fd_install_data(fd, vf); |
76 | if (ret < 0) { |
77 | put_unused_fd(fd); |
78 | pr_err("v4l: fd install data fail %d.\n", ret); |
79 | return ret; |
80 | } |
81 | |
82 | v4l_buf->m.vf_fd = fd; |
83 | |
84 | return 0; |
85 | } |
86 | EXPORT_SYMBOL(vdec_v4l_binding_fd_and_vf); |
87 | |
88 | int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx, |
89 | struct vdec_v4l2_buffer **out) |
90 | { |
91 | int ret = 0; |
92 | |
93 | if (ctx->drv_handle == 0) |
94 | return -EIO; |
95 | |
96 | ret = ctx->dec_if->get_param(ctx->drv_handle, |
97 | GET_PARAM_FREE_FRAME_BUFFER, out); |
98 | |
99 | return ret; |
100 | } |
101 | EXPORT_SYMBOL(vdec_v4l_get_buffer); |
102 | |
103 | int vdec_v4l_set_pic_infos(struct aml_vcodec_ctx *ctx, |
104 | struct aml_vdec_pic_infos *info) |
105 | { |
106 | int ret = 0; |
107 | |
108 | if (ctx->drv_handle == 0) |
109 | return -EIO; |
110 | |
111 | ret = ctx->dec_if->set_param(ctx->drv_handle, |
112 | SET_PARAM_PIC_INFO, info); |
113 | |
114 | return ret; |
115 | } |
116 | EXPORT_SYMBOL(vdec_v4l_set_pic_infos); |
117 | |
118 | int vdec_v4l_write_frame_sync(struct aml_vcodec_ctx *ctx) |
119 | { |
120 | int ret = 0; |
121 | |
122 | if (ctx->drv_handle == 0) |
123 | return -EIO; |
124 | |
125 | ret = ctx->dec_if->set_param(ctx->drv_handle, |
126 | SET_PARAM_WRITE_FRAME_SYNC, NULL); |
127 | |
128 | return ret; |
129 | } |
130 | EXPORT_SYMBOL(vdec_v4l_write_frame_sync); |
131 | |
132 |