18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Memory-to-memory device framework for Video for Linux 2. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Helper functions for devices that use memory buffers for both source 68c2ecf20Sopenharmony_ci * and destination. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Copyright (c) 2009 Samsung Electronics Co., Ltd. 98c2ecf20Sopenharmony_ci * Pawel Osciak, <pawel@osciak.com> 108c2ecf20Sopenharmony_ci * Marek Szyprowski, <m.szyprowski@samsung.com> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef _MEDIA_V4L2_MEM2MEM_H 148c2ecf20Sopenharmony_ci#define _MEDIA_V4L2_MEM2MEM_H 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <media/videobuf2-v4l2.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/** 198c2ecf20Sopenharmony_ci * struct v4l2_m2m_ops - mem-to-mem device driver callbacks 208c2ecf20Sopenharmony_ci * @device_run: required. Begin the actual job (transaction) inside this 218c2ecf20Sopenharmony_ci * callback. 228c2ecf20Sopenharmony_ci * The job does NOT have to end before this callback returns 238c2ecf20Sopenharmony_ci * (and it will be the usual case). When the job finishes, 248c2ecf20Sopenharmony_ci * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() 258c2ecf20Sopenharmony_ci * has to be called. 268c2ecf20Sopenharmony_ci * @job_ready: optional. Should return 0 if the driver does not have a job 278c2ecf20Sopenharmony_ci * fully prepared to run yet (i.e. it will not be able to finish a 288c2ecf20Sopenharmony_ci * transaction without sleeping). If not provided, it will be 298c2ecf20Sopenharmony_ci * assumed that one source and one destination buffer are all 308c2ecf20Sopenharmony_ci * that is required for the driver to perform one full transaction. 318c2ecf20Sopenharmony_ci * This method may not sleep. 328c2ecf20Sopenharmony_ci * @job_abort: optional. Informs the driver that it has to abort the currently 338c2ecf20Sopenharmony_ci * running transaction as soon as possible (i.e. as soon as it can 348c2ecf20Sopenharmony_ci * stop the device safely; e.g. in the next interrupt handler), 358c2ecf20Sopenharmony_ci * even if the transaction would not have been finished by then. 368c2ecf20Sopenharmony_ci * After the driver performs the necessary steps, it has to call 378c2ecf20Sopenharmony_ci * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() as 388c2ecf20Sopenharmony_ci * if the transaction ended normally. 398c2ecf20Sopenharmony_ci * This function does not have to (and will usually not) wait 408c2ecf20Sopenharmony_ci * until the device enters a state when it can be stopped. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_cistruct v4l2_m2m_ops { 438c2ecf20Sopenharmony_ci void (*device_run)(void *priv); 448c2ecf20Sopenharmony_ci int (*job_ready)(void *priv); 458c2ecf20Sopenharmony_ci void (*job_abort)(void *priv); 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistruct video_device; 498c2ecf20Sopenharmony_cistruct v4l2_m2m_dev; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/** 528c2ecf20Sopenharmony_ci * struct v4l2_m2m_queue_ctx - represents a queue for buffers ready to be 538c2ecf20Sopenharmony_ci * processed 548c2ecf20Sopenharmony_ci * 558c2ecf20Sopenharmony_ci * @q: pointer to struct &vb2_queue 568c2ecf20Sopenharmony_ci * @rdy_queue: List of V4L2 mem-to-mem queues 578c2ecf20Sopenharmony_ci * @rdy_spinlock: spin lock to protect the struct usage 588c2ecf20Sopenharmony_ci * @num_rdy: number of buffers ready to be processed 598c2ecf20Sopenharmony_ci * @buffered: is the queue buffered? 608c2ecf20Sopenharmony_ci * 618c2ecf20Sopenharmony_ci * Queue for buffers ready to be processed as soon as this 628c2ecf20Sopenharmony_ci * instance receives access to the device. 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistruct v4l2_m2m_queue_ctx { 668c2ecf20Sopenharmony_ci struct vb2_queue q; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci struct list_head rdy_queue; 698c2ecf20Sopenharmony_ci spinlock_t rdy_spinlock; 708c2ecf20Sopenharmony_ci u8 num_rdy; 718c2ecf20Sopenharmony_ci bool buffered; 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/** 758c2ecf20Sopenharmony_ci * struct v4l2_m2m_ctx - Memory to memory context structure 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * @q_lock: struct &mutex lock 788c2ecf20Sopenharmony_ci * @new_frame: valid in the device_run callback: if true, then this 798c2ecf20Sopenharmony_ci * starts a new frame; if false, then this is a new slice 808c2ecf20Sopenharmony_ci * for an existing frame. This is always true unless 818c2ecf20Sopenharmony_ci * V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF is set, which 828c2ecf20Sopenharmony_ci * indicates slicing support. 838c2ecf20Sopenharmony_ci * @is_draining: indicates device is in draining phase 848c2ecf20Sopenharmony_ci * @last_src_buf: indicate the last source buffer for draining 858c2ecf20Sopenharmony_ci * @next_buf_last: next capture queud buffer will be tagged as last 868c2ecf20Sopenharmony_ci * @has_stopped: indicate the device has been stopped 878c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 888c2ecf20Sopenharmony_ci * @cap_q_ctx: Capture (output to memory) queue context 898c2ecf20Sopenharmony_ci * @out_q_ctx: Output (input from memory) queue context 908c2ecf20Sopenharmony_ci * @queue: List of memory to memory contexts 918c2ecf20Sopenharmony_ci * @job_flags: Job queue flags, used internally by v4l2-mem2mem.c: 928c2ecf20Sopenharmony_ci * %TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT. 938c2ecf20Sopenharmony_ci * @finished: Wait queue used to signalize when a job queue finished. 948c2ecf20Sopenharmony_ci * @priv: Instance private data 958c2ecf20Sopenharmony_ci * 968c2ecf20Sopenharmony_ci * The memory to memory context is specific to a file handle, NOT to e.g. 978c2ecf20Sopenharmony_ci * a device. 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_cistruct v4l2_m2m_ctx { 1008c2ecf20Sopenharmony_ci /* optional cap/out vb2 queues lock */ 1018c2ecf20Sopenharmony_ci struct mutex *q_lock; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci bool new_frame; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci bool is_draining; 1068c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *last_src_buf; 1078c2ecf20Sopenharmony_ci bool next_buf_last; 1088c2ecf20Sopenharmony_ci bool has_stopped; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci /* internal use only */ 1118c2ecf20Sopenharmony_ci struct v4l2_m2m_dev *m2m_dev; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci struct v4l2_m2m_queue_ctx cap_q_ctx; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci struct v4l2_m2m_queue_ctx out_q_ctx; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci /* For device job queue */ 1188c2ecf20Sopenharmony_ci struct list_head queue; 1198c2ecf20Sopenharmony_ci unsigned long job_flags; 1208c2ecf20Sopenharmony_ci wait_queue_head_t finished; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci void *priv; 1238c2ecf20Sopenharmony_ci}; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci/** 1268c2ecf20Sopenharmony_ci * struct v4l2_m2m_buffer - Memory to memory buffer 1278c2ecf20Sopenharmony_ci * 1288c2ecf20Sopenharmony_ci * @vb: pointer to struct &vb2_v4l2_buffer 1298c2ecf20Sopenharmony_ci * @list: list of m2m buffers 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_cistruct v4l2_m2m_buffer { 1328c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer vb; 1338c2ecf20Sopenharmony_ci struct list_head list; 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/** 1378c2ecf20Sopenharmony_ci * v4l2_m2m_get_curr_priv() - return driver private data for the currently 1388c2ecf20Sopenharmony_ci * running instance or NULL if no instance is running 1398c2ecf20Sopenharmony_ci * 1408c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 1418c2ecf20Sopenharmony_ci */ 1428c2ecf20Sopenharmony_civoid *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci/** 1458c2ecf20Sopenharmony_ci * v4l2_m2m_get_vq() - return vb2_queue for the given type 1468c2ecf20Sopenharmony_ci * 1478c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 1488c2ecf20Sopenharmony_ci * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type 1498c2ecf20Sopenharmony_ci */ 1508c2ecf20Sopenharmony_cistruct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, 1518c2ecf20Sopenharmony_ci enum v4l2_buf_type type); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci/** 1548c2ecf20Sopenharmony_ci * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to 1558c2ecf20Sopenharmony_ci * the pending job queue and add it if so. 1568c2ecf20Sopenharmony_ci * 1578c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 1588c2ecf20Sopenharmony_ci * 1598c2ecf20Sopenharmony_ci * There are three basic requirements an instance has to meet to be able to run: 1608c2ecf20Sopenharmony_ci * 1) at least one source buffer has to be queued, 1618c2ecf20Sopenharmony_ci * 2) at least one destination buffer has to be queued, 1628c2ecf20Sopenharmony_ci * 3) streaming has to be on. 1638c2ecf20Sopenharmony_ci * 1648c2ecf20Sopenharmony_ci * If a queue is buffered (for example a decoder hardware ringbuffer that has 1658c2ecf20Sopenharmony_ci * to be drained before doing streamoff), allow scheduling without v4l2 buffers 1668c2ecf20Sopenharmony_ci * on that queue. 1678c2ecf20Sopenharmony_ci * 1688c2ecf20Sopenharmony_ci * There may also be additional, custom requirements. In such case the driver 1698c2ecf20Sopenharmony_ci * should supply a custom callback (job_ready in v4l2_m2m_ops) that should 1708c2ecf20Sopenharmony_ci * return 1 if the instance is ready. 1718c2ecf20Sopenharmony_ci * An example of the above could be an instance that requires more than one 1728c2ecf20Sopenharmony_ci * src/dst buffer per transaction. 1738c2ecf20Sopenharmony_ci */ 1748c2ecf20Sopenharmony_civoid v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/** 1778c2ecf20Sopenharmony_ci * v4l2_m2m_job_finish() - inform the framework that a job has been finished 1788c2ecf20Sopenharmony_ci * and have it clean up 1798c2ecf20Sopenharmony_ci * 1808c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 1818c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 1828c2ecf20Sopenharmony_ci * 1838c2ecf20Sopenharmony_ci * Called by a driver to yield back the device after it has finished with it. 1848c2ecf20Sopenharmony_ci * Should be called as soon as possible after reaching a state which allows 1858c2ecf20Sopenharmony_ci * other instances to take control of the device. 1868c2ecf20Sopenharmony_ci * 1878c2ecf20Sopenharmony_ci * This function has to be called only after &v4l2_m2m_ops->device_run 1888c2ecf20Sopenharmony_ci * callback has been called on the driver. To prevent recursion, it should 1898c2ecf20Sopenharmony_ci * not be called directly from the &v4l2_m2m_ops->device_run callback though. 1908c2ecf20Sopenharmony_ci */ 1918c2ecf20Sopenharmony_civoid v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, 1928c2ecf20Sopenharmony_ci struct v4l2_m2m_ctx *m2m_ctx); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci/** 1958c2ecf20Sopenharmony_ci * v4l2_m2m_buf_done_and_job_finish() - return source/destination buffers with 1968c2ecf20Sopenharmony_ci * state and inform the framework that a job has been finished and have it 1978c2ecf20Sopenharmony_ci * clean up 1988c2ecf20Sopenharmony_ci * 1998c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 2008c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 2018c2ecf20Sopenharmony_ci * @state: vb2 buffer state passed to v4l2_m2m_buf_done(). 2028c2ecf20Sopenharmony_ci * 2038c2ecf20Sopenharmony_ci * Drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this 2048c2ecf20Sopenharmony_ci * function instead of job_finish() to take held buffers into account. It is 2058c2ecf20Sopenharmony_ci * optional for other drivers. 2068c2ecf20Sopenharmony_ci * 2078c2ecf20Sopenharmony_ci * This function removes the source buffer from the ready list and returns 2088c2ecf20Sopenharmony_ci * it with the given state. The same is done for the destination buffer, unless 2098c2ecf20Sopenharmony_ci * it is marked 'held'. In that case the buffer is kept on the ready list. 2108c2ecf20Sopenharmony_ci * 2118c2ecf20Sopenharmony_ci * After that the job is finished (see job_finish()). 2128c2ecf20Sopenharmony_ci * 2138c2ecf20Sopenharmony_ci * This allows for multiple output buffers to be used to fill in a single 2148c2ecf20Sopenharmony_ci * capture buffer. This is typically used by stateless decoders where 2158c2ecf20Sopenharmony_ci * multiple e.g. H.264 slices contribute to a single decoded frame. 2168c2ecf20Sopenharmony_ci */ 2178c2ecf20Sopenharmony_civoid v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, 2188c2ecf20Sopenharmony_ci struct v4l2_m2m_ctx *m2m_ctx, 2198c2ecf20Sopenharmony_ci enum vb2_buffer_state state); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_cistatic inline void 2228c2ecf20Sopenharmony_civ4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci vb2_buffer_done(&buf->vb2_buf, state); 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci/** 2288c2ecf20Sopenharmony_ci * v4l2_m2m_clear_state() - clear encoding/decoding state 2298c2ecf20Sopenharmony_ci * 2308c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_cistatic inline void 2338c2ecf20Sopenharmony_civ4l2_m2m_clear_state(struct v4l2_m2m_ctx *m2m_ctx) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci m2m_ctx->next_buf_last = false; 2368c2ecf20Sopenharmony_ci m2m_ctx->is_draining = false; 2378c2ecf20Sopenharmony_ci m2m_ctx->has_stopped = false; 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci/** 2418c2ecf20Sopenharmony_ci * v4l2_m2m_mark_stopped() - set current encoding/decoding state as stopped 2428c2ecf20Sopenharmony_ci * 2438c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 2448c2ecf20Sopenharmony_ci */ 2458c2ecf20Sopenharmony_cistatic inline void 2468c2ecf20Sopenharmony_civ4l2_m2m_mark_stopped(struct v4l2_m2m_ctx *m2m_ctx) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci m2m_ctx->next_buf_last = false; 2498c2ecf20Sopenharmony_ci m2m_ctx->is_draining = false; 2508c2ecf20Sopenharmony_ci m2m_ctx->has_stopped = true; 2518c2ecf20Sopenharmony_ci} 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci/** 2548c2ecf20Sopenharmony_ci * v4l2_m2m_dst_buf_is_last() - return the current encoding/decoding session 2558c2ecf20Sopenharmony_ci * draining management state of next queued capture buffer 2568c2ecf20Sopenharmony_ci * 2578c2ecf20Sopenharmony_ci * This last capture buffer should be tagged with V4L2_BUF_FLAG_LAST to notify 2588c2ecf20Sopenharmony_ci * the end of the capture session. 2598c2ecf20Sopenharmony_ci * 2608c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_cistatic inline bool 2638c2ecf20Sopenharmony_civ4l2_m2m_dst_buf_is_last(struct v4l2_m2m_ctx *m2m_ctx) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci return m2m_ctx->is_draining && m2m_ctx->next_buf_last; 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci/** 2698c2ecf20Sopenharmony_ci * v4l2_m2m_has_stopped() - return the current encoding/decoding session 2708c2ecf20Sopenharmony_ci * stopped state 2718c2ecf20Sopenharmony_ci * 2728c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 2738c2ecf20Sopenharmony_ci */ 2748c2ecf20Sopenharmony_cistatic inline bool 2758c2ecf20Sopenharmony_civ4l2_m2m_has_stopped(struct v4l2_m2m_ctx *m2m_ctx) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci return m2m_ctx->has_stopped; 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci/** 2818c2ecf20Sopenharmony_ci * v4l2_m2m_is_last_draining_src_buf() - return the output buffer draining 2828c2ecf20Sopenharmony_ci * state in the current encoding/decoding session 2838c2ecf20Sopenharmony_ci * 2848c2ecf20Sopenharmony_ci * This will identify the last output buffer queued before a session stop 2858c2ecf20Sopenharmony_ci * was required, leading to an actual encoding/decoding session stop state 2868c2ecf20Sopenharmony_ci * in the encoding/decoding process after being processed. 2878c2ecf20Sopenharmony_ci * 2888c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 2898c2ecf20Sopenharmony_ci * @vbuf: pointer to struct &v4l2_buffer 2908c2ecf20Sopenharmony_ci */ 2918c2ecf20Sopenharmony_cistatic inline bool 2928c2ecf20Sopenharmony_civ4l2_m2m_is_last_draining_src_buf(struct v4l2_m2m_ctx *m2m_ctx, 2938c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *vbuf) 2948c2ecf20Sopenharmony_ci{ 2958c2ecf20Sopenharmony_ci return m2m_ctx->is_draining && vbuf == m2m_ctx->last_src_buf; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci/** 2998c2ecf20Sopenharmony_ci * v4l2_m2m_last_buffer_done() - marks the buffer with LAST flag and DONE 3008c2ecf20Sopenharmony_ci * 3018c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3028c2ecf20Sopenharmony_ci * @vbuf: pointer to struct &v4l2_buffer 3038c2ecf20Sopenharmony_ci */ 3048c2ecf20Sopenharmony_civoid v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, 3058c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *vbuf); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci/** 3088c2ecf20Sopenharmony_ci * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job 3098c2ecf20Sopenharmony_ci * to finish 3108c2ecf20Sopenharmony_ci * 3118c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 3128c2ecf20Sopenharmony_ci * 3138c2ecf20Sopenharmony_ci * Called by a driver in the suspend hook. Stop new jobs from being run, and 3148c2ecf20Sopenharmony_ci * wait for current running job to finish. 3158c2ecf20Sopenharmony_ci */ 3168c2ecf20Sopenharmony_civoid v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci/** 3198c2ecf20Sopenharmony_ci * v4l2_m2m_resume() - resume job running and try to run a queued job 3208c2ecf20Sopenharmony_ci * 3218c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 3228c2ecf20Sopenharmony_ci * 3238c2ecf20Sopenharmony_ci * Called by a driver in the resume hook. This reverts the operation of 3248c2ecf20Sopenharmony_ci * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if 3258c2ecf20Sopenharmony_ci * there is any. 3268c2ecf20Sopenharmony_ci */ 3278c2ecf20Sopenharmony_civoid v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci/** 3308c2ecf20Sopenharmony_ci * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer 3318c2ecf20Sopenharmony_ci * 3328c2ecf20Sopenharmony_ci * @file: pointer to struct &file 3338c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3348c2ecf20Sopenharmony_ci * @reqbufs: pointer to struct &v4l2_requestbuffers 3358c2ecf20Sopenharmony_ci */ 3368c2ecf20Sopenharmony_ciint v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 3378c2ecf20Sopenharmony_ci struct v4l2_requestbuffers *reqbufs); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci/** 3408c2ecf20Sopenharmony_ci * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer 3418c2ecf20Sopenharmony_ci * 3428c2ecf20Sopenharmony_ci * @file: pointer to struct &file 3438c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3448c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer 3458c2ecf20Sopenharmony_ci * 3468c2ecf20Sopenharmony_ci * See v4l2_m2m_mmap() documentation for details. 3478c2ecf20Sopenharmony_ci */ 3488c2ecf20Sopenharmony_ciint v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 3498c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci/** 3528c2ecf20Sopenharmony_ci * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on 3538c2ecf20Sopenharmony_ci * the type 3548c2ecf20Sopenharmony_ci * 3558c2ecf20Sopenharmony_ci * @file: pointer to struct &file 3568c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3578c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer 3588c2ecf20Sopenharmony_ci */ 3598c2ecf20Sopenharmony_ciint v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 3608c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci/** 3638c2ecf20Sopenharmony_ci * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on 3648c2ecf20Sopenharmony_ci * the type 3658c2ecf20Sopenharmony_ci * 3668c2ecf20Sopenharmony_ci * @file: pointer to struct &file 3678c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3688c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer 3698c2ecf20Sopenharmony_ci */ 3708c2ecf20Sopenharmony_ciint v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 3718c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci/** 3748c2ecf20Sopenharmony_ci * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on 3758c2ecf20Sopenharmony_ci * the type 3768c2ecf20Sopenharmony_ci * 3778c2ecf20Sopenharmony_ci * @file: pointer to struct &file 3788c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3798c2ecf20Sopenharmony_ci * @buf: pointer to struct &v4l2_buffer 3808c2ecf20Sopenharmony_ci */ 3818c2ecf20Sopenharmony_ciint v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 3828c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci/** 3858c2ecf20Sopenharmony_ci * v4l2_m2m_create_bufs() - create a source or destination buffer, depending 3868c2ecf20Sopenharmony_ci * on the type 3878c2ecf20Sopenharmony_ci * 3888c2ecf20Sopenharmony_ci * @file: pointer to struct &file 3898c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 3908c2ecf20Sopenharmony_ci * @create: pointer to struct &v4l2_create_buffers 3918c2ecf20Sopenharmony_ci */ 3928c2ecf20Sopenharmony_ciint v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 3938c2ecf20Sopenharmony_ci struct v4l2_create_buffers *create); 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci/** 3968c2ecf20Sopenharmony_ci * v4l2_m2m_expbuf() - export a source or destination buffer, depending on 3978c2ecf20Sopenharmony_ci * the type 3988c2ecf20Sopenharmony_ci * 3998c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4008c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4018c2ecf20Sopenharmony_ci * @eb: pointer to struct &v4l2_exportbuffer 4028c2ecf20Sopenharmony_ci */ 4038c2ecf20Sopenharmony_ciint v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4048c2ecf20Sopenharmony_ci struct v4l2_exportbuffer *eb); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci/** 4078c2ecf20Sopenharmony_ci * v4l2_m2m_streamon() - turn on streaming for a video queue 4088c2ecf20Sopenharmony_ci * 4098c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4108c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4118c2ecf20Sopenharmony_ci * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type 4128c2ecf20Sopenharmony_ci */ 4138c2ecf20Sopenharmony_ciint v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4148c2ecf20Sopenharmony_ci enum v4l2_buf_type type); 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci/** 4178c2ecf20Sopenharmony_ci * v4l2_m2m_streamoff() - turn off streaming for a video queue 4188c2ecf20Sopenharmony_ci * 4198c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4208c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4218c2ecf20Sopenharmony_ci * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type 4228c2ecf20Sopenharmony_ci */ 4238c2ecf20Sopenharmony_ciint v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4248c2ecf20Sopenharmony_ci enum v4l2_buf_type type); 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci/** 4278c2ecf20Sopenharmony_ci * v4l2_m2m_update_start_streaming_state() - update the encoding/decoding 4288c2ecf20Sopenharmony_ci * session state when a start of streaming of a video queue is requested 4298c2ecf20Sopenharmony_ci * 4308c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4318c2ecf20Sopenharmony_ci * @q: queue 4328c2ecf20Sopenharmony_ci */ 4338c2ecf20Sopenharmony_civoid v4l2_m2m_update_start_streaming_state(struct v4l2_m2m_ctx *m2m_ctx, 4348c2ecf20Sopenharmony_ci struct vb2_queue *q); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci/** 4378c2ecf20Sopenharmony_ci * v4l2_m2m_update_stop_streaming_state() - update the encoding/decoding 4388c2ecf20Sopenharmony_ci * session state when a stop of streaming of a video queue is requested 4398c2ecf20Sopenharmony_ci * 4408c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4418c2ecf20Sopenharmony_ci * @q: queue 4428c2ecf20Sopenharmony_ci */ 4438c2ecf20Sopenharmony_civoid v4l2_m2m_update_stop_streaming_state(struct v4l2_m2m_ctx *m2m_ctx, 4448c2ecf20Sopenharmony_ci struct vb2_queue *q); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci/** 4478c2ecf20Sopenharmony_ci * v4l2_m2m_encoder_cmd() - execute an encoder command 4488c2ecf20Sopenharmony_ci * 4498c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4508c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4518c2ecf20Sopenharmony_ci * @ec: pointer to the encoder command 4528c2ecf20Sopenharmony_ci */ 4538c2ecf20Sopenharmony_ciint v4l2_m2m_encoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4548c2ecf20Sopenharmony_ci struct v4l2_encoder_cmd *ec); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci/** 4578c2ecf20Sopenharmony_ci * v4l2_m2m_decoder_cmd() - execute a decoder command 4588c2ecf20Sopenharmony_ci * 4598c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4608c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4618c2ecf20Sopenharmony_ci * @dc: pointer to the decoder command 4628c2ecf20Sopenharmony_ci */ 4638c2ecf20Sopenharmony_ciint v4l2_m2m_decoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4648c2ecf20Sopenharmony_ci struct v4l2_decoder_cmd *dc); 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci/** 4678c2ecf20Sopenharmony_ci * v4l2_m2m_poll() - poll replacement, for destination buffers only 4688c2ecf20Sopenharmony_ci * 4698c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4708c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4718c2ecf20Sopenharmony_ci * @wait: pointer to struct &poll_table_struct 4728c2ecf20Sopenharmony_ci * 4738c2ecf20Sopenharmony_ci * Call from the driver's poll() function. Will poll both queues. If a buffer 4748c2ecf20Sopenharmony_ci * is available to dequeue (with dqbuf) from the source queue, this will 4758c2ecf20Sopenharmony_ci * indicate that a non-blocking write can be performed, while read will be 4768c2ecf20Sopenharmony_ci * returned in case of the destination queue. 4778c2ecf20Sopenharmony_ci */ 4788c2ecf20Sopenharmony_ci__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4798c2ecf20Sopenharmony_ci struct poll_table_struct *wait); 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci/** 4828c2ecf20Sopenharmony_ci * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer 4838c2ecf20Sopenharmony_ci * 4848c2ecf20Sopenharmony_ci * @file: pointer to struct &file 4858c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 4868c2ecf20Sopenharmony_ci * @vma: pointer to struct &vm_area_struct 4878c2ecf20Sopenharmony_ci * 4888c2ecf20Sopenharmony_ci * Call from driver's mmap() function. Will handle mmap() for both queues 4898c2ecf20Sopenharmony_ci * seamlessly for videobuffer, which will receive normal per-queue offsets and 4908c2ecf20Sopenharmony_ci * proper videobuf queue pointers. The differentiation is made outside videobuf 4918c2ecf20Sopenharmony_ci * by adding a predefined offset to buffers from one of the queues and 4928c2ecf20Sopenharmony_ci * subtracting it before passing it back to videobuf. Only drivers (and 4938c2ecf20Sopenharmony_ci * thus applications) receive modified offsets. 4948c2ecf20Sopenharmony_ci */ 4958c2ecf20Sopenharmony_ciint v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 4968c2ecf20Sopenharmony_ci struct vm_area_struct *vma); 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci/** 4998c2ecf20Sopenharmony_ci * v4l2_m2m_init() - initialize per-driver m2m data 5008c2ecf20Sopenharmony_ci * 5018c2ecf20Sopenharmony_ci * @m2m_ops: pointer to struct v4l2_m2m_ops 5028c2ecf20Sopenharmony_ci * 5038c2ecf20Sopenharmony_ci * Usually called from driver's ``probe()`` function. 5048c2ecf20Sopenharmony_ci * 5058c2ecf20Sopenharmony_ci * Return: returns an opaque pointer to the internal data to handle M2M context 5068c2ecf20Sopenharmony_ci */ 5078c2ecf20Sopenharmony_cistruct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci#if defined(CONFIG_MEDIA_CONTROLLER) 5108c2ecf20Sopenharmony_civoid v4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev); 5118c2ecf20Sopenharmony_ciint v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev, 5128c2ecf20Sopenharmony_ci struct video_device *vdev, int function); 5138c2ecf20Sopenharmony_ci#else 5148c2ecf20Sopenharmony_cistatic inline void 5158c2ecf20Sopenharmony_civ4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev) 5168c2ecf20Sopenharmony_ci{ 5178c2ecf20Sopenharmony_ci} 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_cistatic inline int 5208c2ecf20Sopenharmony_civ4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev, 5218c2ecf20Sopenharmony_ci struct video_device *vdev, int function) 5228c2ecf20Sopenharmony_ci{ 5238c2ecf20Sopenharmony_ci return 0; 5248c2ecf20Sopenharmony_ci} 5258c2ecf20Sopenharmony_ci#endif 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci/** 5288c2ecf20Sopenharmony_ci * v4l2_m2m_release() - cleans up and frees a m2m_dev structure 5298c2ecf20Sopenharmony_ci * 5308c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 5318c2ecf20Sopenharmony_ci * 5328c2ecf20Sopenharmony_ci * Usually called from driver's ``remove()`` function. 5338c2ecf20Sopenharmony_ci */ 5348c2ecf20Sopenharmony_civoid v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci/** 5378c2ecf20Sopenharmony_ci * v4l2_m2m_ctx_init() - allocate and initialize a m2m context 5388c2ecf20Sopenharmony_ci * 5398c2ecf20Sopenharmony_ci * @m2m_dev: opaque pointer to the internal data to handle M2M context 5408c2ecf20Sopenharmony_ci * @drv_priv: driver's instance private data 5418c2ecf20Sopenharmony_ci * @queue_init: a callback for queue type-specific initialization function 5428c2ecf20Sopenharmony_ci * to be used for initializing videobuf_queues 5438c2ecf20Sopenharmony_ci * 5448c2ecf20Sopenharmony_ci * Usually called from driver's ``open()`` function. 5458c2ecf20Sopenharmony_ci */ 5468c2ecf20Sopenharmony_cistruct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev, 5478c2ecf20Sopenharmony_ci void *drv_priv, 5488c2ecf20Sopenharmony_ci int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)); 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_set_src_buffered(struct v4l2_m2m_ctx *m2m_ctx, 5518c2ecf20Sopenharmony_ci bool buffered) 5528c2ecf20Sopenharmony_ci{ 5538c2ecf20Sopenharmony_ci m2m_ctx->out_q_ctx.buffered = buffered; 5548c2ecf20Sopenharmony_ci} 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_set_dst_buffered(struct v4l2_m2m_ctx *m2m_ctx, 5578c2ecf20Sopenharmony_ci bool buffered) 5588c2ecf20Sopenharmony_ci{ 5598c2ecf20Sopenharmony_ci m2m_ctx->cap_q_ctx.buffered = buffered; 5608c2ecf20Sopenharmony_ci} 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci/** 5638c2ecf20Sopenharmony_ci * v4l2_m2m_ctx_release() - release m2m context 5648c2ecf20Sopenharmony_ci * 5658c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 5668c2ecf20Sopenharmony_ci * 5678c2ecf20Sopenharmony_ci * Usually called from driver's release() function. 5688c2ecf20Sopenharmony_ci */ 5698c2ecf20Sopenharmony_civoid v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci/** 5728c2ecf20Sopenharmony_ci * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. 5738c2ecf20Sopenharmony_ci * 5748c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 5758c2ecf20Sopenharmony_ci * @vbuf: pointer to struct &vb2_v4l2_buffer 5768c2ecf20Sopenharmony_ci * 5778c2ecf20Sopenharmony_ci * Call from videobuf_queue_ops->ops->buf_queue, videobuf_queue_ops callback. 5788c2ecf20Sopenharmony_ci */ 5798c2ecf20Sopenharmony_civoid v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, 5808c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *vbuf); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci/** 5838c2ecf20Sopenharmony_ci * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for 5848c2ecf20Sopenharmony_ci * use 5858c2ecf20Sopenharmony_ci * 5868c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 5878c2ecf20Sopenharmony_ci */ 5888c2ecf20Sopenharmony_cistatic inline 5898c2ecf20Sopenharmony_ciunsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) 5908c2ecf20Sopenharmony_ci{ 5918c2ecf20Sopenharmony_ci unsigned int num_buf_rdy; 5928c2ecf20Sopenharmony_ci unsigned long flags; 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_ci spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); 5958c2ecf20Sopenharmony_ci num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy; 5968c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci return num_buf_rdy; 5998c2ecf20Sopenharmony_ci} 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci/** 6028c2ecf20Sopenharmony_ci * v4l2_m2m_num_dst_bufs_ready() - return the number of destination buffers 6038c2ecf20Sopenharmony_ci * ready for use 6048c2ecf20Sopenharmony_ci * 6058c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6068c2ecf20Sopenharmony_ci */ 6078c2ecf20Sopenharmony_cistatic inline 6088c2ecf20Sopenharmony_ciunsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci unsigned int num_buf_rdy; 6118c2ecf20Sopenharmony_ci unsigned long flags; 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); 6148c2ecf20Sopenharmony_ci num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy; 6158c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci return num_buf_rdy; 6188c2ecf20Sopenharmony_ci} 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci/** 6218c2ecf20Sopenharmony_ci * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers 6228c2ecf20Sopenharmony_ci * 6238c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx 6248c2ecf20Sopenharmony_ci */ 6258c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci/** 6288c2ecf20Sopenharmony_ci * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready 6298c2ecf20Sopenharmony_ci * buffers 6308c2ecf20Sopenharmony_ci * 6318c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6328c2ecf20Sopenharmony_ci */ 6338c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 6348c2ecf20Sopenharmony_civ4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) 6358c2ecf20Sopenharmony_ci{ 6368c2ecf20Sopenharmony_ci return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx); 6378c2ecf20Sopenharmony_ci} 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci/** 6408c2ecf20Sopenharmony_ci * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of 6418c2ecf20Sopenharmony_ci * ready buffers 6428c2ecf20Sopenharmony_ci * 6438c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6448c2ecf20Sopenharmony_ci */ 6458c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 6468c2ecf20Sopenharmony_civ4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) 6478c2ecf20Sopenharmony_ci{ 6488c2ecf20Sopenharmony_ci return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx); 6498c2ecf20Sopenharmony_ci} 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci/** 6528c2ecf20Sopenharmony_ci * v4l2_m2m_last_buf() - return last buffer from the list of ready buffers 6538c2ecf20Sopenharmony_ci * 6548c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx 6558c2ecf20Sopenharmony_ci */ 6568c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *v4l2_m2m_last_buf(struct v4l2_m2m_queue_ctx *q_ctx); 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci/** 6598c2ecf20Sopenharmony_ci * v4l2_m2m_last_src_buf() - return last destination buffer from the list of 6608c2ecf20Sopenharmony_ci * ready buffers 6618c2ecf20Sopenharmony_ci * 6628c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6638c2ecf20Sopenharmony_ci */ 6648c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 6658c2ecf20Sopenharmony_civ4l2_m2m_last_src_buf(struct v4l2_m2m_ctx *m2m_ctx) 6668c2ecf20Sopenharmony_ci{ 6678c2ecf20Sopenharmony_ci return v4l2_m2m_last_buf(&m2m_ctx->out_q_ctx); 6688c2ecf20Sopenharmony_ci} 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci/** 6718c2ecf20Sopenharmony_ci * v4l2_m2m_last_dst_buf() - return last destination buffer from the list of 6728c2ecf20Sopenharmony_ci * ready buffers 6738c2ecf20Sopenharmony_ci * 6748c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6758c2ecf20Sopenharmony_ci */ 6768c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 6778c2ecf20Sopenharmony_civ4l2_m2m_last_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) 6788c2ecf20Sopenharmony_ci{ 6798c2ecf20Sopenharmony_ci return v4l2_m2m_last_buf(&m2m_ctx->cap_q_ctx); 6808c2ecf20Sopenharmony_ci} 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_ci/** 6838c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready 6848c2ecf20Sopenharmony_ci * buffers 6858c2ecf20Sopenharmony_ci * 6868c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6878c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer 6888c2ecf20Sopenharmony_ci */ 6898c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b) \ 6908c2ecf20Sopenharmony_ci list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list) 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci/** 6938c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers 6948c2ecf20Sopenharmony_ci * 6958c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 6968c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer 6978c2ecf20Sopenharmony_ci */ 6988c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_src_buf(m2m_ctx, b) \ 6998c2ecf20Sopenharmony_ci list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list) 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci/** 7028c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready 7038c2ecf20Sopenharmony_ci * buffers safely 7048c2ecf20Sopenharmony_ci * 7058c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7068c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer 7078c2ecf20Sopenharmony_ci * @n: used as temporary storage 7088c2ecf20Sopenharmony_ci */ 7098c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n) \ 7108c2ecf20Sopenharmony_ci list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list) 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci/** 7138c2ecf20Sopenharmony_ci * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready 7148c2ecf20Sopenharmony_ci * buffers safely 7158c2ecf20Sopenharmony_ci * 7168c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7178c2ecf20Sopenharmony_ci * @b: current buffer of type struct v4l2_m2m_buffer 7188c2ecf20Sopenharmony_ci * @n: used as temporary storage 7198c2ecf20Sopenharmony_ci */ 7208c2ecf20Sopenharmony_ci#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n) \ 7218c2ecf20Sopenharmony_ci list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list) 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci/** 7248c2ecf20Sopenharmony_ci * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers 7258c2ecf20Sopenharmony_ci * 7268c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7278c2ecf20Sopenharmony_ci */ 7288c2ecf20Sopenharmony_cistatic inline 7298c2ecf20Sopenharmony_cistruct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) 7308c2ecf20Sopenharmony_ci{ 7318c2ecf20Sopenharmony_ci return &m2m_ctx->out_q_ctx.q; 7328c2ecf20Sopenharmony_ci} 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci/** 7358c2ecf20Sopenharmony_ci * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers 7368c2ecf20Sopenharmony_ci * 7378c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7388c2ecf20Sopenharmony_ci */ 7398c2ecf20Sopenharmony_cistatic inline 7408c2ecf20Sopenharmony_cistruct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) 7418c2ecf20Sopenharmony_ci{ 7428c2ecf20Sopenharmony_ci return &m2m_ctx->cap_q_ctx.q; 7438c2ecf20Sopenharmony_ci} 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci/** 7468c2ecf20Sopenharmony_ci * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and 7478c2ecf20Sopenharmony_ci * return it 7488c2ecf20Sopenharmony_ci * 7498c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx 7508c2ecf20Sopenharmony_ci */ 7518c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci/** 7548c2ecf20Sopenharmony_ci * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready 7558c2ecf20Sopenharmony_ci * buffers and return it 7568c2ecf20Sopenharmony_ci * 7578c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7588c2ecf20Sopenharmony_ci */ 7598c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 7608c2ecf20Sopenharmony_civ4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) 7618c2ecf20Sopenharmony_ci{ 7628c2ecf20Sopenharmony_ci return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx); 7638c2ecf20Sopenharmony_ci} 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci/** 7668c2ecf20Sopenharmony_ci * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of 7678c2ecf20Sopenharmony_ci * ready buffers and return it 7688c2ecf20Sopenharmony_ci * 7698c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7708c2ecf20Sopenharmony_ci */ 7718c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 7728c2ecf20Sopenharmony_civ4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) 7738c2ecf20Sopenharmony_ci{ 7748c2ecf20Sopenharmony_ci return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx); 7758c2ecf20Sopenharmony_ci} 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci/** 7788c2ecf20Sopenharmony_ci * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready 7798c2ecf20Sopenharmony_ci * buffers 7808c2ecf20Sopenharmony_ci * 7818c2ecf20Sopenharmony_ci * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx 7828c2ecf20Sopenharmony_ci * @vbuf: the buffer to be removed 7838c2ecf20Sopenharmony_ci */ 7848c2ecf20Sopenharmony_civoid v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx, 7858c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *vbuf); 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci/** 7888c2ecf20Sopenharmony_ci * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the list 7898c2ecf20Sopenharmony_ci * of ready buffers 7908c2ecf20Sopenharmony_ci * 7918c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 7928c2ecf20Sopenharmony_ci * @vbuf: the buffer to be removed 7938c2ecf20Sopenharmony_ci */ 7948c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx, 7958c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *vbuf) 7968c2ecf20Sopenharmony_ci{ 7978c2ecf20Sopenharmony_ci v4l2_m2m_buf_remove_by_buf(&m2m_ctx->out_q_ctx, vbuf); 7988c2ecf20Sopenharmony_ci} 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci/** 8018c2ecf20Sopenharmony_ci * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from the 8028c2ecf20Sopenharmony_ci * list of ready buffers 8038c2ecf20Sopenharmony_ci * 8048c2ecf20Sopenharmony_ci * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx 8058c2ecf20Sopenharmony_ci * @vbuf: the buffer to be removed 8068c2ecf20Sopenharmony_ci */ 8078c2ecf20Sopenharmony_cistatic inline void v4l2_m2m_dst_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx, 8088c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *vbuf) 8098c2ecf20Sopenharmony_ci{ 8108c2ecf20Sopenharmony_ci v4l2_m2m_buf_remove_by_buf(&m2m_ctx->cap_q_ctx, vbuf); 8118c2ecf20Sopenharmony_ci} 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_cistruct vb2_v4l2_buffer * 8148c2ecf20Sopenharmony_civ4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx); 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 8178c2ecf20Sopenharmony_civ4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx) 8188c2ecf20Sopenharmony_ci{ 8198c2ecf20Sopenharmony_ci return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx); 8208c2ecf20Sopenharmony_ci} 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_cistatic inline struct vb2_v4l2_buffer * 8238c2ecf20Sopenharmony_civ4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx) 8248c2ecf20Sopenharmony_ci{ 8258c2ecf20Sopenharmony_ci return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx); 8268c2ecf20Sopenharmony_ci} 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci/** 8298c2ecf20Sopenharmony_ci * v4l2_m2m_buf_copy_metadata() - copy buffer metadata from 8308c2ecf20Sopenharmony_ci * the output buffer to the capture buffer 8318c2ecf20Sopenharmony_ci * 8328c2ecf20Sopenharmony_ci * @out_vb: the output buffer that is the source of the metadata. 8338c2ecf20Sopenharmony_ci * @cap_vb: the capture buffer that will receive the metadata. 8348c2ecf20Sopenharmony_ci * @copy_frame_flags: copy the KEY/B/PFRAME flags as well. 8358c2ecf20Sopenharmony_ci * 8368c2ecf20Sopenharmony_ci * This helper function copies the timestamp, timecode (if the TIMECODE 8378c2ecf20Sopenharmony_ci * buffer flag was set), field and the TIMECODE, KEYFRAME, BFRAME, PFRAME 8388c2ecf20Sopenharmony_ci * and TSTAMP_SRC_MASK flags from @out_vb to @cap_vb. 8398c2ecf20Sopenharmony_ci * 8408c2ecf20Sopenharmony_ci * If @copy_frame_flags is false, then the KEYFRAME, BFRAME and PFRAME 8418c2ecf20Sopenharmony_ci * flags are not copied. This is typically needed for encoders that 8428c2ecf20Sopenharmony_ci * set this bits explicitly. 8438c2ecf20Sopenharmony_ci */ 8448c2ecf20Sopenharmony_civoid v4l2_m2m_buf_copy_metadata(const struct vb2_v4l2_buffer *out_vb, 8458c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *cap_vb, 8468c2ecf20Sopenharmony_ci bool copy_frame_flags); 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci/* v4l2 request helper */ 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_civoid v4l2_m2m_request_queue(struct media_request *req); 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci/* v4l2 ioctl helpers */ 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv, 8558c2ecf20Sopenharmony_ci struct v4l2_requestbuffers *rb); 8568c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh, 8578c2ecf20Sopenharmony_ci struct v4l2_create_buffers *create); 8588c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_querybuf(struct file *file, void *fh, 8598c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 8608c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_expbuf(struct file *file, void *fh, 8618c2ecf20Sopenharmony_ci struct v4l2_exportbuffer *eb); 8628c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_qbuf(struct file *file, void *fh, 8638c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 8648c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh, 8658c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 8668c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_prepare_buf(struct file *file, void *fh, 8678c2ecf20Sopenharmony_ci struct v4l2_buffer *buf); 8688c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_streamon(struct file *file, void *fh, 8698c2ecf20Sopenharmony_ci enum v4l2_buf_type type); 8708c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_streamoff(struct file *file, void *fh, 8718c2ecf20Sopenharmony_ci enum v4l2_buf_type type); 8728c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_encoder_cmd(struct file *file, void *fh, 8738c2ecf20Sopenharmony_ci struct v4l2_encoder_cmd *ec); 8748c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_decoder_cmd(struct file *file, void *fh, 8758c2ecf20Sopenharmony_ci struct v4l2_decoder_cmd *dc); 8768c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *fh, 8778c2ecf20Sopenharmony_ci struct v4l2_encoder_cmd *ec); 8788c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh, 8798c2ecf20Sopenharmony_ci struct v4l2_decoder_cmd *dc); 8808c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh, 8818c2ecf20Sopenharmony_ci struct v4l2_decoder_cmd *dc); 8828c2ecf20Sopenharmony_ciint v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv, 8838c2ecf20Sopenharmony_ci struct v4l2_decoder_cmd *dc); 8848c2ecf20Sopenharmony_ciint v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma); 8858c2ecf20Sopenharmony_ci__poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait); 8868c2ecf20Sopenharmony_ci 8878c2ecf20Sopenharmony_ci#endif /* _MEDIA_V4L2_MEM2MEM_H */ 8888c2ecf20Sopenharmony_ci 889