mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 05:31:15 +00:00
nvencoder: Fix b-frame encoding on Linux
On Windows, Win32 event handle is used to wait for encoded output, but it's not available on Linux. We should delay bitstream locking if encoder returns "need-more-input" Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4004>
This commit is contained in:
parent
0b52663815
commit
b1c14b0357
2 changed files with 36 additions and 2 deletions
|
@ -367,6 +367,7 @@ GstNvEncObject::InitSession (NV_ENC_INITIALIZE_PARAMS * params,
|
|||
}
|
||||
|
||||
task_size_ = task_size;
|
||||
lookahead_ = params->encodeConfig->rcParams.lookaheadDepth;
|
||||
initialized_ = true;
|
||||
|
||||
out:
|
||||
|
@ -490,8 +491,34 @@ GstNvEncObject::Encode (GstVideoCodecFrame * codec_frame,
|
|||
active_resource_queue_.insert (task->resource);
|
||||
}
|
||||
|
||||
/* On Windows and if async encoding is enabled, output thread will wait
|
||||
* for completion event. But on Linux, async encoding is not supported.
|
||||
* So, we should wait for NV_ENC_SUCCESS in case of sync mode
|
||||
* (it would introduce latency though).
|
||||
* Otherwise nvEncLockBitstream() will return error */
|
||||
if (params.completionEvent) {
|
||||
/* Windows only path */
|
||||
task_queue_.push (task);
|
||||
cond_.notify_all ();
|
||||
} else {
|
||||
pending_task_queue_.push (task);
|
||||
if (status == NV_ENC_SUCCESS) {
|
||||
bool notify = false;
|
||||
|
||||
/* XXX: nvEncLockBitstream() will return NV_ENC_ERR_INVALID_PARAM
|
||||
* if lookahead is enabled. See also
|
||||
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/494
|
||||
*/
|
||||
while (pending_task_queue_.size() > lookahead_) {
|
||||
notify = true;
|
||||
task_queue_.push (pending_task_queue_.front ());
|
||||
pending_task_queue_.pop ();
|
||||
}
|
||||
|
||||
if (notify)
|
||||
cond_.notify_all ();
|
||||
}
|
||||
}
|
||||
|
||||
return NV_ENC_SUCCESS;
|
||||
}
|
||||
|
@ -531,6 +558,11 @@ GstNvEncObject::Drain (GstNvEncTask * task)
|
|||
break;
|
||||
} while (true);
|
||||
|
||||
while (!pending_task_queue_.empty ()) {
|
||||
task_queue_.push (pending_task_queue_.front ());
|
||||
pending_task_queue_.pop ();
|
||||
}
|
||||
|
||||
task_queue_.push (task);
|
||||
cond_.notify_all ();
|
||||
|
||||
|
|
|
@ -233,6 +233,7 @@ private:
|
|||
/* list of GstNvEncResource in task_queue */
|
||||
std::set <GstNvEncResource *> active_resource_queue_;
|
||||
std::queue <GstNvEncTask *> task_queue_;
|
||||
std::queue <GstNvEncTask *> pending_task_queue_;
|
||||
std::queue <GstNvEncTask *> empty_task_queue_;
|
||||
gint64 user_token_;
|
||||
GstCudaContext *context_ = nullptr;
|
||||
|
@ -245,6 +246,7 @@ private:
|
|||
bool initialized_ = false;
|
||||
bool flushing_ = false;
|
||||
guint task_size_ = 0;
|
||||
guint lookahead_ = 0;
|
||||
|
||||
NV_ENC_DEVICE_TYPE device_type_ = NV_ENC_DEVICE_TYPE_CUDA;
|
||||
NV_ENC_BUFFER_FORMAT buffer_format_ = NV_ENC_BUFFER_FORMAT_UNDEFINED;
|
||||
|
|
Loading…
Reference in a new issue