| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Memory-to-memory device framework for Video for Linux 2. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 7 | 8 | * Copyright (c) 2009 Samsung Electronics Co., Ltd. |
|---|
| 8 | 9 | * Pawel Osciak, <pawel@osciak.com> |
|---|
| 9 | 10 | * Marek Szyprowski, <m.szyprowski@samsung.com> |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 12 | | - * it under the terms of the GNU General Public License as published by the |
|---|
| 13 | | - * Free Software Foundation; either version 2 of the |
|---|
| 14 | | - * License, or (at your option) any later version |
|---|
| 15 | 11 | */ |
|---|
| 16 | 12 | |
|---|
| 17 | 13 | #ifndef _MEDIA_V4L2_MEM2MEM_H |
|---|
| .. | .. |
|---|
| 25 | 21 | * callback. |
|---|
| 26 | 22 | * The job does NOT have to end before this callback returns |
|---|
| 27 | 23 | * (and it will be the usual case). When the job finishes, |
|---|
| 28 | | - * v4l2_m2m_job_finish() has to be called. |
|---|
| 24 | + * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() |
|---|
| 25 | + * has to be called. |
|---|
| 29 | 26 | * @job_ready: optional. Should return 0 if the driver does not have a job |
|---|
| 30 | 27 | * fully prepared to run yet (i.e. it will not be able to finish a |
|---|
| 31 | 28 | * transaction without sleeping). If not provided, it will be |
|---|
| .. | .. |
|---|
| 37 | 34 | * stop the device safely; e.g. in the next interrupt handler), |
|---|
| 38 | 35 | * even if the transaction would not have been finished by then. |
|---|
| 39 | 36 | * After the driver performs the necessary steps, it has to call |
|---|
| 40 | | - * v4l2_m2m_job_finish() (as if the transaction ended normally). |
|---|
| 37 | + * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() as |
|---|
| 38 | + * if the transaction ended normally. |
|---|
| 41 | 39 | * This function does not have to (and will usually not) wait |
|---|
| 42 | 40 | * until the device enters a state when it can be stopped. |
|---|
| 43 | 41 | */ |
|---|
| .. | .. |
|---|
| 77 | 75 | * struct v4l2_m2m_ctx - Memory to memory context structure |
|---|
| 78 | 76 | * |
|---|
| 79 | 77 | * @q_lock: struct &mutex lock |
|---|
| 78 | + * @new_frame: valid in the device_run callback: if true, then this |
|---|
| 79 | + * starts a new frame; if false, then this is a new slice |
|---|
| 80 | + * for an existing frame. This is always true unless |
|---|
| 81 | + * V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF is set, which |
|---|
| 82 | + * indicates slicing support. |
|---|
| 83 | + * @is_draining: indicates device is in draining phase |
|---|
| 84 | + * @last_src_buf: indicate the last source buffer for draining |
|---|
| 85 | + * @next_buf_last: next capture queud buffer will be tagged as last |
|---|
| 86 | + * @has_stopped: indicate the device has been stopped |
|---|
| 80 | 87 | * @m2m_dev: opaque pointer to the internal data to handle M2M context |
|---|
| 81 | 88 | * @cap_q_ctx: Capture (output to memory) queue context |
|---|
| 82 | 89 | * @out_q_ctx: Output (input from memory) queue context |
|---|
| .. | .. |
|---|
| 92 | 99 | struct v4l2_m2m_ctx { |
|---|
| 93 | 100 | /* optional cap/out vb2 queues lock */ |
|---|
| 94 | 101 | struct mutex *q_lock; |
|---|
| 102 | + |
|---|
| 103 | + bool new_frame; |
|---|
| 104 | + |
|---|
| 105 | + bool is_draining; |
|---|
| 106 | + struct vb2_v4l2_buffer *last_src_buf; |
|---|
| 107 | + bool next_buf_last; |
|---|
| 108 | + bool has_stopped; |
|---|
| 95 | 109 | |
|---|
| 96 | 110 | /* internal use only */ |
|---|
| 97 | 111 | struct v4l2_m2m_dev *m2m_dev; |
|---|
| .. | .. |
|---|
| 177 | 191 | void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, |
|---|
| 178 | 192 | struct v4l2_m2m_ctx *m2m_ctx); |
|---|
| 179 | 193 | |
|---|
| 194 | +/** |
|---|
| 195 | + * v4l2_m2m_buf_done_and_job_finish() - return source/destination buffers with |
|---|
| 196 | + * state and inform the framework that a job has been finished and have it |
|---|
| 197 | + * clean up |
|---|
| 198 | + * |
|---|
| 199 | + * @m2m_dev: opaque pointer to the internal data to handle M2M context |
|---|
| 200 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 201 | + * @state: vb2 buffer state passed to v4l2_m2m_buf_done(). |
|---|
| 202 | + * |
|---|
| 203 | + * Drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this |
|---|
| 204 | + * function instead of job_finish() to take held buffers into account. It is |
|---|
| 205 | + * optional for other drivers. |
|---|
| 206 | + * |
|---|
| 207 | + * This function removes the source buffer from the ready list and returns |
|---|
| 208 | + * it with the given state. The same is done for the destination buffer, unless |
|---|
| 209 | + * it is marked 'held'. In that case the buffer is kept on the ready list. |
|---|
| 210 | + * |
|---|
| 211 | + * After that the job is finished (see job_finish()). |
|---|
| 212 | + * |
|---|
| 213 | + * This allows for multiple output buffers to be used to fill in a single |
|---|
| 214 | + * capture buffer. This is typically used by stateless decoders where |
|---|
| 215 | + * multiple e.g. H.264 slices contribute to a single decoded frame. |
|---|
| 216 | + */ |
|---|
| 217 | +void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, |
|---|
| 218 | + struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 219 | + enum vb2_buffer_state state); |
|---|
| 220 | + |
|---|
| 180 | 221 | static inline void |
|---|
| 181 | 222 | v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) |
|---|
| 182 | 223 | { |
|---|
| 183 | 224 | vb2_buffer_done(&buf->vb2_buf, state); |
|---|
| 184 | 225 | } |
|---|
| 226 | + |
|---|
| 227 | +/** |
|---|
| 228 | + * v4l2_m2m_clear_state() - clear encoding/decoding state |
|---|
| 229 | + * |
|---|
| 230 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 231 | + */ |
|---|
| 232 | +static inline void |
|---|
| 233 | +v4l2_m2m_clear_state(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 234 | +{ |
|---|
| 235 | + m2m_ctx->next_buf_last = false; |
|---|
| 236 | + m2m_ctx->is_draining = false; |
|---|
| 237 | + m2m_ctx->has_stopped = false; |
|---|
| 238 | +} |
|---|
| 239 | + |
|---|
| 240 | +/** |
|---|
| 241 | + * v4l2_m2m_mark_stopped() - set current encoding/decoding state as stopped |
|---|
| 242 | + * |
|---|
| 243 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 244 | + */ |
|---|
| 245 | +static inline void |
|---|
| 246 | +v4l2_m2m_mark_stopped(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 247 | +{ |
|---|
| 248 | + m2m_ctx->next_buf_last = false; |
|---|
| 249 | + m2m_ctx->is_draining = false; |
|---|
| 250 | + m2m_ctx->has_stopped = true; |
|---|
| 251 | +} |
|---|
| 252 | + |
|---|
| 253 | +/** |
|---|
| 254 | + * v4l2_m2m_dst_buf_is_last() - return the current encoding/decoding session |
|---|
| 255 | + * draining management state of next queued capture buffer |
|---|
| 256 | + * |
|---|
| 257 | + * This last capture buffer should be tagged with V4L2_BUF_FLAG_LAST to notify |
|---|
| 258 | + * the end of the capture session. |
|---|
| 259 | + * |
|---|
| 260 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 261 | + */ |
|---|
| 262 | +static inline bool |
|---|
| 263 | +v4l2_m2m_dst_buf_is_last(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 264 | +{ |
|---|
| 265 | + return m2m_ctx->is_draining && m2m_ctx->next_buf_last; |
|---|
| 266 | +} |
|---|
| 267 | + |
|---|
| 268 | +/** |
|---|
| 269 | + * v4l2_m2m_has_stopped() - return the current encoding/decoding session |
|---|
| 270 | + * stopped state |
|---|
| 271 | + * |
|---|
| 272 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 273 | + */ |
|---|
| 274 | +static inline bool |
|---|
| 275 | +v4l2_m2m_has_stopped(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 276 | +{ |
|---|
| 277 | + return m2m_ctx->has_stopped; |
|---|
| 278 | +} |
|---|
| 279 | + |
|---|
| 280 | +/** |
|---|
| 281 | + * v4l2_m2m_is_last_draining_src_buf() - return the output buffer draining |
|---|
| 282 | + * state in the current encoding/decoding session |
|---|
| 283 | + * |
|---|
| 284 | + * This will identify the last output buffer queued before a session stop |
|---|
| 285 | + * was required, leading to an actual encoding/decoding session stop state |
|---|
| 286 | + * in the encoding/decoding process after being processed. |
|---|
| 287 | + * |
|---|
| 288 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 289 | + * @vbuf: pointer to struct &v4l2_buffer |
|---|
| 290 | + */ |
|---|
| 291 | +static inline bool |
|---|
| 292 | +v4l2_m2m_is_last_draining_src_buf(struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 293 | + struct vb2_v4l2_buffer *vbuf) |
|---|
| 294 | +{ |
|---|
| 295 | + return m2m_ctx->is_draining && vbuf == m2m_ctx->last_src_buf; |
|---|
| 296 | +} |
|---|
| 297 | + |
|---|
| 298 | +/** |
|---|
| 299 | + * v4l2_m2m_last_buffer_done() - marks the buffer with LAST flag and DONE |
|---|
| 300 | + * |
|---|
| 301 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 302 | + * @vbuf: pointer to struct &v4l2_buffer |
|---|
| 303 | + */ |
|---|
| 304 | +void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 305 | + struct vb2_v4l2_buffer *vbuf); |
|---|
| 306 | + |
|---|
| 307 | +/** |
|---|
| 308 | + * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job |
|---|
| 309 | + * to finish |
|---|
| 310 | + * |
|---|
| 311 | + * @m2m_dev: opaque pointer to the internal data to handle M2M context |
|---|
| 312 | + * |
|---|
| 313 | + * Called by a driver in the suspend hook. Stop new jobs from being run, and |
|---|
| 314 | + * wait for current running job to finish. |
|---|
| 315 | + */ |
|---|
| 316 | +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev); |
|---|
| 317 | + |
|---|
| 318 | +/** |
|---|
| 319 | + * v4l2_m2m_resume() - resume job running and try to run a queued job |
|---|
| 320 | + * |
|---|
| 321 | + * @m2m_dev: opaque pointer to the internal data to handle M2M context |
|---|
| 322 | + * |
|---|
| 323 | + * Called by a driver in the resume hook. This reverts the operation of |
|---|
| 324 | + * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if |
|---|
| 325 | + * there is any. |
|---|
| 326 | + */ |
|---|
| 327 | +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev); |
|---|
| 185 | 328 | |
|---|
| 186 | 329 | /** |
|---|
| 187 | 330 | * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer |
|---|
| .. | .. |
|---|
| 279 | 422 | */ |
|---|
| 280 | 423 | int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 281 | 424 | enum v4l2_buf_type type); |
|---|
| 425 | + |
|---|
| 426 | +/** |
|---|
| 427 | + * v4l2_m2m_update_start_streaming_state() - update the encoding/decoding |
|---|
| 428 | + * session state when a start of streaming of a video queue is requested |
|---|
| 429 | + * |
|---|
| 430 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 431 | + * @q: queue |
|---|
| 432 | + */ |
|---|
| 433 | +void v4l2_m2m_update_start_streaming_state(struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 434 | + struct vb2_queue *q); |
|---|
| 435 | + |
|---|
| 436 | +/** |
|---|
| 437 | + * v4l2_m2m_update_stop_streaming_state() - update the encoding/decoding |
|---|
| 438 | + * session state when a stop of streaming of a video queue is requested |
|---|
| 439 | + * |
|---|
| 440 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 441 | + * @q: queue |
|---|
| 442 | + */ |
|---|
| 443 | +void v4l2_m2m_update_stop_streaming_state(struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 444 | + struct vb2_queue *q); |
|---|
| 445 | + |
|---|
| 446 | +/** |
|---|
| 447 | + * v4l2_m2m_encoder_cmd() - execute an encoder command |
|---|
| 448 | + * |
|---|
| 449 | + * @file: pointer to struct &file |
|---|
| 450 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 451 | + * @ec: pointer to the encoder command |
|---|
| 452 | + */ |
|---|
| 453 | +int v4l2_m2m_encoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 454 | + struct v4l2_encoder_cmd *ec); |
|---|
| 455 | + |
|---|
| 456 | +/** |
|---|
| 457 | + * v4l2_m2m_decoder_cmd() - execute a decoder command |
|---|
| 458 | + * |
|---|
| 459 | + * @file: pointer to struct &file |
|---|
| 460 | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 461 | + * @dc: pointer to the decoder command |
|---|
| 462 | + */ |
|---|
| 463 | +int v4l2_m2m_decoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, |
|---|
| 464 | + struct v4l2_decoder_cmd *dc); |
|---|
| 282 | 465 | |
|---|
| 283 | 466 | /** |
|---|
| 284 | 467 | * v4l2_m2m_poll() - poll replacement, for destination buffers only |
|---|
| .. | .. |
|---|
| 405 | 588 | static inline |
|---|
| 406 | 589 | unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 407 | 590 | { |
|---|
| 408 | | - return m2m_ctx->out_q_ctx.num_rdy; |
|---|
| 591 | + unsigned int num_buf_rdy; |
|---|
| 592 | + unsigned long flags; |
|---|
| 593 | + |
|---|
| 594 | + spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); |
|---|
| 595 | + num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy; |
|---|
| 596 | + spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); |
|---|
| 597 | + |
|---|
| 598 | + return num_buf_rdy; |
|---|
| 409 | 599 | } |
|---|
| 410 | 600 | |
|---|
| 411 | 601 | /** |
|---|
| .. | .. |
|---|
| 417 | 607 | static inline |
|---|
| 418 | 608 | unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 419 | 609 | { |
|---|
| 420 | | - return m2m_ctx->cap_q_ctx.num_rdy; |
|---|
| 610 | + unsigned int num_buf_rdy; |
|---|
| 611 | + unsigned long flags; |
|---|
| 612 | + |
|---|
| 613 | + spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); |
|---|
| 614 | + num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy; |
|---|
| 615 | + spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); |
|---|
| 616 | + |
|---|
| 617 | + return num_buf_rdy; |
|---|
| 421 | 618 | } |
|---|
| 422 | 619 | |
|---|
| 423 | 620 | /** |
|---|
| .. | .. |
|---|
| 425 | 622 | * |
|---|
| 426 | 623 | * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx |
|---|
| 427 | 624 | */ |
|---|
| 428 | | -void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); |
|---|
| 625 | +struct vb2_v4l2_buffer *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); |
|---|
| 429 | 626 | |
|---|
| 430 | 627 | /** |
|---|
| 431 | 628 | * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready |
|---|
| .. | .. |
|---|
| 433 | 630 | * |
|---|
| 434 | 631 | * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 435 | 632 | */ |
|---|
| 436 | | -static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 633 | +static inline struct vb2_v4l2_buffer * |
|---|
| 634 | +v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 437 | 635 | { |
|---|
| 438 | 636 | return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx); |
|---|
| 439 | 637 | } |
|---|
| .. | .. |
|---|
| 444 | 642 | * |
|---|
| 445 | 643 | * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 446 | 644 | */ |
|---|
| 447 | | -static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 645 | +static inline struct vb2_v4l2_buffer * |
|---|
| 646 | +v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 448 | 647 | { |
|---|
| 449 | 648 | return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx); |
|---|
| 450 | 649 | } |
|---|
| .. | .. |
|---|
| 454 | 653 | * |
|---|
| 455 | 654 | * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx |
|---|
| 456 | 655 | */ |
|---|
| 457 | | -void *v4l2_m2m_last_buf(struct v4l2_m2m_queue_ctx *q_ctx); |
|---|
| 656 | +struct vb2_v4l2_buffer *v4l2_m2m_last_buf(struct v4l2_m2m_queue_ctx *q_ctx); |
|---|
| 458 | 657 | |
|---|
| 459 | 658 | /** |
|---|
| 460 | 659 | * v4l2_m2m_last_src_buf() - return last destination buffer from the list of |
|---|
| .. | .. |
|---|
| 462 | 661 | * |
|---|
| 463 | 662 | * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 464 | 663 | */ |
|---|
| 465 | | -static inline void *v4l2_m2m_last_src_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 664 | +static inline struct vb2_v4l2_buffer * |
|---|
| 665 | +v4l2_m2m_last_src_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 466 | 666 | { |
|---|
| 467 | 667 | return v4l2_m2m_last_buf(&m2m_ctx->out_q_ctx); |
|---|
| 468 | 668 | } |
|---|
| .. | .. |
|---|
| 473 | 673 | * |
|---|
| 474 | 674 | * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 475 | 675 | */ |
|---|
| 476 | | -static inline void *v4l2_m2m_last_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 676 | +static inline struct vb2_v4l2_buffer * |
|---|
| 677 | +v4l2_m2m_last_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 477 | 678 | { |
|---|
| 478 | 679 | return v4l2_m2m_last_buf(&m2m_ctx->cap_q_ctx); |
|---|
| 479 | 680 | } |
|---|
| .. | .. |
|---|
| 547 | 748 | * |
|---|
| 548 | 749 | * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx |
|---|
| 549 | 750 | */ |
|---|
| 550 | | -void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); |
|---|
| 751 | +struct vb2_v4l2_buffer *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); |
|---|
| 551 | 752 | |
|---|
| 552 | 753 | /** |
|---|
| 553 | 754 | * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready |
|---|
| .. | .. |
|---|
| 555 | 756 | * |
|---|
| 556 | 757 | * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 557 | 758 | */ |
|---|
| 558 | | -static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 759 | +static inline struct vb2_v4l2_buffer * |
|---|
| 760 | +v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 559 | 761 | { |
|---|
| 560 | 762 | return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx); |
|---|
| 561 | 763 | } |
|---|
| .. | .. |
|---|
| 566 | 768 | * |
|---|
| 567 | 769 | * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx |
|---|
| 568 | 770 | */ |
|---|
| 569 | | -static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 771 | +static inline struct vb2_v4l2_buffer * |
|---|
| 772 | +v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) |
|---|
| 570 | 773 | { |
|---|
| 571 | 774 | return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx); |
|---|
| 572 | 775 | } |
|---|
| .. | .. |
|---|
| 622 | 825 | return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx); |
|---|
| 623 | 826 | } |
|---|
| 624 | 827 | |
|---|
| 828 | +/** |
|---|
| 829 | + * v4l2_m2m_buf_copy_metadata() - copy buffer metadata from |
|---|
| 830 | + * the output buffer to the capture buffer |
|---|
| 831 | + * |
|---|
| 832 | + * @out_vb: the output buffer that is the source of the metadata. |
|---|
| 833 | + * @cap_vb: the capture buffer that will receive the metadata. |
|---|
| 834 | + * @copy_frame_flags: copy the KEY/B/PFRAME flags as well. |
|---|
| 835 | + * |
|---|
| 836 | + * This helper function copies the timestamp, timecode (if the TIMECODE |
|---|
| 837 | + * buffer flag was set), field and the TIMECODE, KEYFRAME, BFRAME, PFRAME |
|---|
| 838 | + * and TSTAMP_SRC_MASK flags from @out_vb to @cap_vb. |
|---|
| 839 | + * |
|---|
| 840 | + * If @copy_frame_flags is false, then the KEYFRAME, BFRAME and PFRAME |
|---|
| 841 | + * flags are not copied. This is typically needed for encoders that |
|---|
| 842 | + * set this bits explicitly. |
|---|
| 843 | + */ |
|---|
| 844 | +void v4l2_m2m_buf_copy_metadata(const struct vb2_v4l2_buffer *out_vb, |
|---|
| 845 | + struct vb2_v4l2_buffer *cap_vb, |
|---|
| 846 | + bool copy_frame_flags); |
|---|
| 847 | + |
|---|
| 848 | +/* v4l2 request helper */ |
|---|
| 849 | + |
|---|
| 850 | +void v4l2_m2m_request_queue(struct media_request *req); |
|---|
| 851 | + |
|---|
| 625 | 852 | /* v4l2 ioctl helpers */ |
|---|
| 626 | 853 | |
|---|
| 627 | 854 | int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv, |
|---|
| .. | .. |
|---|
| 642 | 869 | enum v4l2_buf_type type); |
|---|
| 643 | 870 | int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh, |
|---|
| 644 | 871 | enum v4l2_buf_type type); |
|---|
| 872 | +int v4l2_m2m_ioctl_encoder_cmd(struct file *file, void *fh, |
|---|
| 873 | + struct v4l2_encoder_cmd *ec); |
|---|
| 874 | +int v4l2_m2m_ioctl_decoder_cmd(struct file *file, void *fh, |
|---|
| 875 | + struct v4l2_decoder_cmd *dc); |
|---|
| 876 | +int v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *fh, |
|---|
| 877 | + struct v4l2_encoder_cmd *ec); |
|---|
| 878 | +int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh, |
|---|
| 879 | + struct v4l2_decoder_cmd *dc); |
|---|
| 880 | +int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh, |
|---|
| 881 | + struct v4l2_decoder_cmd *dc); |
|---|
| 882 | +int v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv, |
|---|
| 883 | + struct v4l2_decoder_cmd *dc); |
|---|
| 645 | 884 | int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma); |
|---|
| 646 | 885 | __poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait); |
|---|
| 647 | 886 | |
|---|