STRUCT V4L2_M2M_CTX(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ struct v4l2_m2m_ctx(9) ✨

okay so bestie, welcome to the Kernel API Manual πŸŽ€ today we're looking at struct v4l2_m2m_ctx β€” the memory-to-memory context structure. yes it's as iconic as it sounds πŸ’…


✨ NAME ✨

struct v4l2_m2m_ctx β€” the memory to memory context structure. that's the whole vibe. she's a context. she does mem2mem. periodt πŸ¦‹


✨ SYNOPSIS ✨

here's the whole glow-up, every field exactly as it lives in the header:

struct v4l2_m2m_ctx {
    struct mutex                    *q_lock;
    bool new_frame;
    bool is_draining;
    struct vb2_v4l2_buffer          *last_src_buf;
    bool next_buf_last;
    bool has_stopped;
    bool ignore_cap_streaming;
    struct v4l2_m2m_dev             *m2m_dev;
    struct v4l2_m2m_queue_ctx       cap_q_ctx;
    struct v4l2_m2m_queue_ctx       out_q_ctx;
    struct list_head                queue;
    unsigned long                   job_flags;
    wait_queue_head_t finished;
    void *priv;
};

ngl that's a lot of fields but we're gonna go through literally every single one, no skips, no cap 🫢


✨ Members ✨

okay bestie, field-by-field, let's get into it:

  • q_lock β€” a struct mutex lock. that's her job, that's what she does πŸ”’
  • new_frame β€” this one's valid in the device_run callback, iykyk. if it's true, then this starts a new frame; if it's false, then this is a new slice for an existing frame πŸ‘‘ and here's the tea: it's always true unless V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF is set β€” and that flag is the one that indicates slicing support. so if you see slicing, that's why πŸ’€
  • is_draining β€” indicates the device is in the draining phase 🚿
  • last_src_buf β€” indicate the last source buffer for draining. she's the last one, she's the final girl 🎬
  • next_buf_last β€” next capture queud buffer will be tagged as last. (yes, "queud" β€” that's how it's spelled in the original, we don't fix, we respect πŸ™ˆ)
  • has_stopped β€” indicate the device has been stopped. she's done, she's out βœ‹
  • ignore_cap_streaming β€” if true, job_ready can be called even if the CAPTURE queue is not streaming πŸ”₯ this lets firmware analyze the bitstream header that arrives on the OUTPUT queue. but β€” and this is important, bestie β€” the driver must implement the job_ready callback correctly to make sure that the requirements for actual decoding are met. like, actually correctly. no vibes-based implementations, fr fr ⚠️
  • m2m_dev β€” an opaque pointer to the internal data to handle the M2M context 🫧 opaque means don't peek, just pass her along
  • cap_q_ctx β€” Capture (output to memory) queue context πŸ“₯
  • out_q_ctx β€” Output (input from memory) queue context πŸ“€
  • queue β€” list of memory to memory contexts πŸ”—
  • job_flags β€” job queue flags, used internally by v4l2-mem2mem.c: TRANS_QUEUED, TRANS_RUNNING and TRANS_ABORT 🏁 internal means internal, don't touch
  • finished β€” wait queue used to signalize when a job queue finished ⏳ that's the "we're done here" signal
  • priv β€” instance private data 🀫 hers, not yours

✨ Description ✨

so here's the main character moment: the memory to memory context is specific to a file handle, NOT to e.g. a device. like, read that again. per file handle. not per device. she belongs to the handle, periodt πŸ‘‘


✨ SEE ALSO ✨

okay this list is long but we do not skip, we do not summarize, we list every single one because that's the assignment πŸ’–

Kernel file ./include/media/v4l2-mem2mem.h alongside: struct v4l2_m2m_ops(9), struct v4l2_m2m_queue_ctx(9), struct v4l2_m2m_buffer(9), v4l2_m2m_get_curr_priv(9), v4l2_m2m_get_vq(9), v4l2_m2m_try_schedule(9), v4l2_m2m_job_finish(9), v4l2_m2m_buf_done_and_job_finish(9), v4l2_m2m_clear_state(9), v4l2_m2m_mark_stopped(9), v4l2_m2m_dst_buf_is_last(9), v4l2_m2m_has_stopped(9), v4l2_m2m_is_last_draining_src_buf(9), v4l2_m2m_last_buffer_done(9), v4l2_m2m_suspend(9), v4l2_m2m_resume(9), v4l2_m2m_reqbufs(9), v4l2_m2m_querybuf(9), v4l2_m2m_qbuf(9), v4l2_m2m_dqbuf(9), v4l2_m2m_prepare_buf(9), v4l2_m2m_create_bufs(9), v4l2_m2m_expbuf(9), v4l2_m2m_streamon(9), v4l2_m2m_streamoff(9), v4l2_m2m_update_start_streaming_state(9), v4l2_m2m_update_stop_streaming_state(9), v4l2_m2m_encoder_cmd(9), v4l2_m2m_decoder_cmd(9), v4l2_m2m_poll(9), v4l2_m2m_mmap(9), v4l2_m2m_init(9), v4l2_m2m_release(9), v4l2_m2m_get(9), v4l2_m2m_put(9), v4l2_m2m_ctx_init(9), v4l2_m2m_ctx_release(9), v4l2_m2m_buf_queue(9), v4l2_m2m_num_src_bufs_ready(9), v4l2_m2m_num_dst_bufs_ready(9), v4l2_m2m_next_buf(9), v4l2_m2m_next_src_buf(9), v4l2_m2m_next_dst_buf(9), v4l2_m2m_last_buf(9), v4l2_m2m_last_src_buf(9), v4l2_m2m_last_dst_buf(9), v4l2_m2m_for_each_dst_buf(9), v4l2_m2m_for_each_src_buf(9), v4l2_m2m_for_each_dst_buf_safe(9), v4l2_m2m_for_each_src_buf_safe(9), v4l2_m2m_get_src_vq(9), v4l2_m2m_get_dst_vq(9), v4l2_m2m_buf_remove(9), v4l2_m2m_src_buf_remove(9), v4l2_m2m_dst_buf_remove(9), v4l2_m2m_buf_remove_by_buf(9), v4l2_m2m_src_buf_remove_by_buf(9), v4l2_m2m_dst_buf_remove_by_buf(9), v4l2_m2m_buf_copy_metadata(9).

like I said. every single one. ate and left no crumbs 🌈


a little sign-off for you bestie: this page lives in ./include/media 🌸 version/date situation is October 2026 ⭐ and the page is, of course, struct v4l2_m2m_ctx(9) πŸ’œ thanks for reading, mwah 🧚
πŸ“¦ where this page comes from