v4l2_m2m_buf...d_job_finish(9)
π v4l2_m2m_buf_done_and_job_finish β bestie's guide to the Kernel API Manual β¨
okay so real talk, this one is from the Kernel API Manual, and it's lowkey the function you call when you're DONE done with a job and you need everything to wrap up cute π
β¨ NAME β¨
v4l2_m2m_buf_done_and_job_finish β hands back your source and destination buffers with their state, tells the framework the job is finished, and lets it do the lil cleanup dance π§Ήπ
πΈ SYNOPSIS πΈ
void v4l2_m2m_buf_done_and_job_finish (struct v4l2_m2m_dev *m2m_dev ,
struct v4l2_m2m_ctx *m2m_ctx , enum vb2_buffer_state state );
π¦ ARGUMENTS π¦
m2m_devβ an opaque pointer to the internal data that handles the M2M context. like, you're not supposed to peek inside, it's giving mystery β¨m2m_ctxβ the m2m context assigned to the instance, handed to you as astruct v4l2_m2m_ctx. this is your context, main character energy πstateβ the vb2 buffer state, passed straight on tov4l2_m2m_buf_done. (so it's a little relay race πββοΈ)
π DESCRIPTION π
so here's the tea β β drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this function instead of job_finish, because they need to take held buffers into account. for every other driver it's optional, no pressure bestie π«Ά
what it does, step by step, no cap:
- it removes the source buffer from the ready list and returns it with the given state.
- same thing for the destination buffer β unless that buffer is marked
'held'. in that case it just stays on the ready list, chillin' π - after all that, the job is finished (see
job_finish).
and why do we even do this?? because it lets multiple output buffers be used to fill in a single capture buffer π―. this is typically used by stateless decoders, where multiple e.g. H.264 slices contribute to a single decoded frame. literally teamwork makes the dream work π
π₯ SEE ALSO π₯
Kernel file ./include/media/v4l2-mem2mem.h, plus the whole friend group π
struct v4l2_m2m_ops(9)struct v4l2_m2m_queue_ctx(9)struct v4l2_m2m_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_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)
and that's the whole page bestie, go forth and finish your jobs responsibly π β¨
β signed off from ./include/media, October 2026, living inside the Kernel API Manual as v4l2_m2m_buf...d_job_finish(9) π¦ππ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms