Blame view

include/media/v4l2-mem2mem.h 6.27 KB
7f98639de   Pawel Osciak   V4L/DVB: add memo...
1
2
3
4
5
6
7
  /*
   * Memory-to-memory device framework for Video for Linux 2.
   *
   * Helper functions for devices that use memory buffers for both source
   * and destination.
   *
   * Copyright (c) 2009 Samsung Electronics Co., Ltd.
950720840   Pawel Osciak   [media] Update Pa...
8
   * Pawel Osciak, <pawel@osciak.com>
7f98639de   Pawel Osciak   V4L/DVB: add memo...
9
10
11
12
13
14
15
16
17
18
   * Marek Szyprowski, <m.szyprowski@samsung.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by the
   * Free Software Foundation; either version 2 of the
   * License, or (at your option) any later version
   */
  
  #ifndef _MEDIA_V4L2_MEM2MEM_H
  #define _MEDIA_V4L2_MEM2MEM_H
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
19
  #include <media/videobuf2-core.h>
7f98639de   Pawel Osciak   V4L/DVB: add memo...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  
  /**
   * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
   * @device_run:	required. Begin the actual job (transaction) inside this
   *		callback.
   *		The job does NOT have to end before this callback returns
   *		(and it will be the usual case). When the job finishes,
   *		v4l2_m2m_job_finish() has to be called.
   * @job_ready:	optional. Should return 0 if the driver does not have a job
   *		fully prepared to run yet (i.e. it will not be able to finish a
   *		transaction without sleeping). If not provided, it will be
   *		assumed that one source and one destination buffer are all
   *		that is required for the driver to perform one full transaction.
   *		This method may not sleep.
   * @job_abort:	required. Informs the driver that it has to abort the currently
   *		running transaction as soon as possible (i.e. as soon as it can
   *		stop the device safely; e.g. in the next interrupt handler),
   *		even if the transaction would not have been finished by then.
   *		After the driver performs the necessary steps, it has to call
   *		v4l2_m2m_job_finish() (as if the transaction ended normally).
   *		This function does not have to (and will usually not) wait
   *		until the device enters a state when it can be stopped.
   */
  struct v4l2_m2m_ops {
  	void (*device_run)(void *priv);
  	int (*job_ready)(void *priv);
  	void (*job_abort)(void *priv);
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
47
48
  	void (*lock)(void *priv);
  	void (*unlock)(void *priv);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
49
50
51
52
53
54
  };
  
  struct v4l2_m2m_dev;
  
  struct v4l2_m2m_queue_ctx {
  /* private: internal use only */
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
55
  	struct vb2_queue	q;
7f98639de   Pawel Osciak   V4L/DVB: add memo...
56
57
58
59
  
  	/* Queue for buffers ready to be processed as soon as this
  	 * instance receives access to the device */
  	struct list_head	rdy_queue;
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
60
  	spinlock_t		rdy_spinlock;
7f98639de   Pawel Osciak   V4L/DVB: add memo...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  	u8			num_rdy;
  };
  
  struct v4l2_m2m_ctx {
  /* private: internal use only */
  	struct v4l2_m2m_dev		*m2m_dev;
  
  	/* Capture (output to memory) queue context */
  	struct v4l2_m2m_queue_ctx	cap_q_ctx;
  
  	/* Output (input from memory) queue context */
  	struct v4l2_m2m_queue_ctx	out_q_ctx;
  
  	/* For device job queue */
  	struct list_head		queue;
  	unsigned long			job_flags;
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
77
  	wait_queue_head_t		finished;
7f98639de   Pawel Osciak   V4L/DVB: add memo...
78
79
80
81
  
  	/* Instance private data */
  	void				*priv;
  };
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
82
83
84
85
  struct v4l2_m2m_buffer {
  	struct vb2_buffer	vb;
  	struct list_head	list;
  };
7f98639de   Pawel Osciak   V4L/DVB: add memo...
86
  void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev);
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
87
  struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
7f98639de   Pawel Osciak   V4L/DVB: add memo...
88
89
90
91
  				       enum v4l2_buf_type type);
  
  void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
  			 struct v4l2_m2m_ctx *m2m_ctx);
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
92
93
94
95
96
  static inline void
  v4l2_m2m_buf_done(struct vb2_buffer *buf, enum vb2_buffer_state state)
  {
  	vb2_buffer_done(buf, state);
  }
7f98639de   Pawel Osciak   V4L/DVB: add memo...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		     struct v4l2_requestbuffers *reqbufs);
  
  int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		      struct v4l2_buffer *buf);
  
  int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		  struct v4l2_buffer *buf);
  int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		   struct v4l2_buffer *buf);
  
  int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		      enum v4l2_buf_type type);
  int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		       enum v4l2_buf_type type);
  
  unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  			   struct poll_table_struct *wait);
  
  int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  		  struct vm_area_struct *vma);
  
  struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops);
  void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
121
122
123
  struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
  		void *drv_priv,
  		int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq));
7f98639de   Pawel Osciak   V4L/DVB: add memo...
124
  void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
125
  void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  
  /**
   * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for
   * use
   */
  static inline
  unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
  {
  	return m2m_ctx->cap_q_ctx.num_rdy;
  }
  
  /**
   * v4l2_m2m_num_src_bufs_ready() - return the number of destination buffers
   * ready for use
   */
  static inline
  unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
  {
  	return m2m_ctx->out_q_ctx.num_rdy;
  }
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
146
  void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
147
148
149
150
151
152
153
  
  /**
   * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready
   * buffers
   */
  static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
  {
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
154
  	return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
155
156
157
158
159
160
161
162
  }
  
  /**
   * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of
   * ready buffers
   */
  static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
  {
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
163
  	return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
164
165
166
  }
  
  /**
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
167
   * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
7f98639de   Pawel Osciak   V4L/DVB: add memo...
168
169
   */
  static inline
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
170
  struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
7f98639de   Pawel Osciak   V4L/DVB: add memo...
171
  {
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
172
  	return &m2m_ctx->out_q_ctx.q;
7f98639de   Pawel Osciak   V4L/DVB: add memo...
173
174
175
  }
  
  /**
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
176
   * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
7f98639de   Pawel Osciak   V4L/DVB: add memo...
177
178
   */
  static inline
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
179
  struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
7f98639de   Pawel Osciak   V4L/DVB: add memo...
180
  {
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
181
  	return &m2m_ctx->cap_q_ctx.q;
7f98639de   Pawel Osciak   V4L/DVB: add memo...
182
  }
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
183
  void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
184
185
186
187
188
189
190
  
  /**
   * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
   * buffers and return it
   */
  static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
  {
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
191
  	return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
192
193
194
195
196
197
198
199
  }
  
  /**
   * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of
   * ready buffers and return it
   */
  static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
  {
908a0d7c5   Marek Szyprowski   [media] v4l: mem2...
200
  	return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
7f98639de   Pawel Osciak   V4L/DVB: add memo...
201
202
203
  }
  
  #endif /* _MEDIA_V4L2_MEM2MEM_H */