/* * Copyright (C) 2026 Markus Fritsche * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. */ #ifndef _REQUEST_POOL_H_ #define _REQUEST_POOL_H_ #include /* * OUTPUT (bitstream-input) buffer pool, decoupled from caller-allocated * VA surfaces. Sizing is driven by codec pipeline depth (typically 4 * for H.264), not by the consumer's surface count. * * The pool owns the V4L2 buffer indices and their mmap pointers. A * decode request "borrows" a slot at vaBeginPicture, fills it across * vaRenderPicture calls, queues it at vaEndPicture, and releases it * after VIDIOC_DQBUF returns. * * This replaces the per-surface OUTPUT-buffer ownership model in the * pre-refactor code, where object_surface.source_* fields permanently * held a single OUTPUT buffer per surface — incorrect because OUTPUT * buffers are request-time resources, not picture-time resources, and * because the per-surface loop in RequestCreateContext only ran when * surfaces_count > 0 (breaking ffmpeg's vaapi-copy num_render_targets=0 * convention). */ struct request_pool_slot { unsigned int index; /* V4L2 buffer index in OUTPUT queue */ void *data; /* mmap pointer for this slot */ unsigned int size; /* mmap size in bytes */ bool busy; /* true while borrowed for a request */ }; struct request_pool { struct request_pool_slot *slots; unsigned int count; unsigned int next; /* round-robin acquire cursor */ bool initialized; }; /* * Allocate count OUTPUT buffers via VIDIOC_CREATE_BUFS, query and mmap * each, populate pool->slots[]. Caller must have already done * VIDIOC_S_FMT on the OUTPUT queue. Returns 0 on success, -1 on * failure. */ int request_pool_init(struct request_pool *pool, int video_fd, unsigned int output_type, unsigned int count); /* * Munmap all slots and free the slots array. Idempotent. */ void request_pool_destroy(struct request_pool *pool); /* * Claim the next free slot (round-robin). Returns the slot's V4L2 * buffer index on success (slot in pool->slots[] is determined by * the returned index), or -1 if all slots are busy. */ int request_pool_acquire(struct request_pool *pool); /* * Mark the slot at pool->slots[i] free for reuse. Caller must pass the * V4L2 buffer index returned earlier from request_pool_acquire(). */ void request_pool_release(struct request_pool *pool, unsigned int index); /* * Look up the pool slot owning a given V4L2 buffer index. Returns * pointer to the slot on success, NULL if the index is out of range. * The returned pointer is valid until pool destruction; do not free. */ struct request_pool_slot *request_pool_slot(struct request_pool *pool, unsigned int index); #endif