nvenc: Refactoring internal buffer pool structure

To support rc-lookahead and bframe encoding, nvenc needs one more
staging queue, because NvEncEncodePicture can return NV_ENC_ERR_NEED_MORE_INPUT
but which was not considered so far.
As documented by NVENC programming guide, pending buffers should wait
other inputs until NvEncEncodePicture returns success.

New encoding flow is
- Submit raw picture buffer to encoder with NvEncEncodePicture
- The submitted input/output buffer pair will be queued to pending_queue
  - If NvEncEncodePicture returned success, then move all pair in pending_queue
    to final stage
  - Otherwise, wait more input raw pictures.

Another change is dropping NV_ENC_LOCK_INPUT_BUFFER usage.
So now nvenc always uses CUDA memory input buffer. As a result,
both opengl and system memory handling are unified.
This commit is contained in:
Seungha Yang 2019-09-02 14:13:26 +09:00
parent e73acbaa5c
commit 94f2843774
2 changed files with 417 additions and 475 deletions

File diff suppressed because it is too large Load diff

View file

@ -104,25 +104,30 @@ typedef struct {
volatile gint reconfig; /* ATOMIC */ volatile gint reconfig; /* ATOMIC */
gboolean gl_input; gboolean gl_input;
/* allocated buffers */ /* array of allocated input/output buffers (GstNvEncFrameState),
gpointer *input_bufs; /* array of n_allocs input buffers */ * and hold the ownership of the GstNvEncFrameState. */
NV_ENC_OUTPUT_PTR *output_bufs; /* array of n_allocs output buffers */ GArray *items;
guint n_bufs; guint n_bufs;
/* input and output buffers currently available */ /* (GstNvEncFrameState) available empty items which could be submitted
GAsyncQueue *in_bufs_pool; * to encoder */
GAsyncQueue *bitstream_pool; GAsyncQueue *available_queue;
/* output bufs in use (input bufs in use are tracked via the codec frames) */ /* (GstNvEncFrameState) submitted to encoder but not ready to finish
GAsyncQueue *bitstream_queue; * (due to bframe or lookhead operation) */
GAsyncQueue *pending_queue;
/* (GstNvEncFrameState) submitted to encoder and ready to finish.
* finished items will go back to available item queue */
GAsyncQueue *bitstream_queue;
/* we spawn a thread that does the (blocking) waits for output buffers /* we spawn a thread that does the (blocking) waits for output buffers
* to become available, so we can continue to feed data to the encoder * to become available, so we can continue to feed data to the encoder
* while we wait */ * while we wait */
GThread *bitstream_thread; GThread *bitstream_thread;
void *display; /* GstGLDisplay */ GstObject *display; /* GstGLDisplay */
void *other_context; /* GstGLContext */ GstObject *other_context; /* GstGLContext */
GstVideoInfo input_info; /* buffer configuration for buffers sent to NVENC */ GstVideoInfo input_info; /* buffer configuration for buffers sent to NVENC */