[x265] [PATCH 1 of 2] encoder: if zero-latency, encode each picture in single call
Steve Borho
steve at borho.org
Wed Jan 21 18:21:34 CET 2015
# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1421860810 21600
# Wed Jan 21 11:20:10 2015 -0600
# Node ID 7aec6406358de473ffe6ec97fa3916cc95a2307c
# Parent 3f7902a3e5e418a192f3d933ead1fa0b0e15349e
encoder: if zero-latency, encode each picture in single call
This patch deliberately doesn't change indentation so the logic changes are
clear. It's fairly ugly but I can't think of a cleaner method to handle the
problem.
diff -r 3f7902a3e5e4 -r 7aec6406358d source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Wed Jan 21 10:17:14 2015 -0600
+++ b/source/encoder/encoder.cpp Wed Jan 21 11:20:10 2015 -0600
@@ -257,6 +257,8 @@
}
}
+ m_bZeroLatency = !m_param->bframes && !m_param->lookaheadDepth && m_param->frameNumThreads == 1;
+
m_aborted |= parseLambdaFile(m_param);
m_encodeStartTime = x265_mdate();
@@ -488,10 +490,21 @@
m_curEncoder = (m_curEncoder + 1) % m_param->frameNumThreads;
int ret = 0;
+ /* Normal operation is to wait for the current frame encoder to complete its current frame
+ * and then to give it a new frame to work on. In zero-latency mode, we must encode this
+ * input picture before returning so the order must be reversed. This do/while() loop allows
+ * us to alternate the order of the calls without ugly code replication */
+ Frame* outFrame = NULL;
+ Frame* frameEnc = NULL;
+ int pass = 0;
+ do
+ {
+
/* getEncodedPicture() should block until the FrameEncoder has completed
* encoding the frame. This is how back-pressure through the API is
* accomplished when the encoder is full */
- Frame *outFrame = curEncoder->getEncodedPicture(m_nalList);
+ if (!m_bZeroLatency || pass)
+ outFrame = curEncoder->getEncodedPicture(m_nalList);
if (outFrame)
{
Slice *slice = outFrame->m_encData->m_slice;
@@ -591,8 +604,9 @@
/* pop a single frame from decided list, then provide to frame encoder
* curEncoder is guaranteed to be idle at this point */
- Frame* frameEnc = m_lookahead->getDecidedPicture();
- if (frameEnc)
+ if (!pass)
+ frameEnc = m_lookahead->getDecidedPicture();
+ if (frameEnc && !pass)
{
/* give this frame a FrameData instance before encoding */
if (m_dpb->m_picSymFreeList)
@@ -655,6 +669,9 @@
else if (m_encodedFrameNum)
m_rateControl->setFinalFrameCount(m_encodedFrameNum);
+ }
+ while (m_bZeroLatency && ++pass < 2);
+
return ret;
}
diff -r 3f7902a3e5e4 -r 7aec6406358d source/encoder/encoder.h
--- a/source/encoder/encoder.h Wed Jan 21 10:17:14 2015 -0600
+++ b/source/encoder/encoder.h Wed Jan 21 11:20:10 2015 -0600
@@ -131,6 +131,7 @@
Lookahead* m_lookahead;
Window m_conformanceWindow;
+ bool m_bZeroLatency; // x265_encoder_encode() returns NALs for the input picture, zero lag
bool m_aborted; // fatal error detected
Encoder();
More information about the x265-devel
mailing list