[x265] [PATCH x265] Cleanup
Aruna Matheswaran
aruna at multicorewareinc.com
Tue Apr 28 11:53:16 CEST 2020
# HG changeset patch
# User Aruna Matheswaran <aruna at multicorewareinc.com>
# Date 1586956494 -19800
# Wed Apr 15 18:44:54 2020 +0530
# Node ID 23da64aedc8e5dcbed9ecd6e531f5649e6906c91
# Parent 94bfe7f2c0c12616145f8fc1a1762ed55204a0a6
Cleanup
diff -r 94bfe7f2c0c1 -r 23da64aedc8e source/abrEncApp.cpp
--- a/source/abrEncApp.cpp Thu Apr 16 18:48:56 2020 +0530
+++ b/source/abrEncApp.cpp Wed Apr 15 18:44:54 2020 +0530
@@ -41,62 +41,6 @@
b_ctrl_c = 1;
}
-#define START_CODE 0x00000001
-#define START_CODE_BYTES 4
-
-/* Parse the RPU file and extract the RPU corresponding to the current picture
-* and fill the rpu field of the input picture */
-static int rpuParser(x265_picture * pic, FILE * ptr)
-{
- uint8_t byteVal;
- uint32_t code = 0;
- int bytesRead = 0;
- pic->rpu.payloadSize = 0;
-
- if (!pic->pts)
- {
- while (bytesRead++ < 4 && fread(&byteVal, sizeof(uint8_t), 1, ptr))
- code = (code << 8) | byteVal;
-
- if (code != START_CODE)
- {
- x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU startcode in POC %d\n", pic->pts);
- return 1;
- }
- }
-
- bytesRead = 0;
- while (fread(&byteVal, sizeof(uint8_t), 1, ptr))
- {
- code = (code << 8) | byteVal;
- if (bytesRead++ < 3)
- continue;
- if (bytesRead >= 1024)
- {
- x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU size in POC %d\n", pic->pts);
- return 1;
- }
-
- if (code != START_CODE)
- pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & 0xFF;
- else
- return 0;
- }
-
- int ShiftBytes = START_CODE_BYTES - (bytesRead - pic->rpu.payloadSize);
- int bytesLeft = bytesRead - pic->rpu.payloadSize;
- code = (code << ShiftBytes * 8);
- for (int i = 0; i < bytesLeft; i++)
- {
- pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & 0xFF;
- code = (code << 8);
- }
- if (!pic->rpu.payloadSize)
- x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU not found for POC %d\n", pic->pts);
- return 0;
-}
-
-
namespace X265_NS {
// private namespace
#define X265_INPUT_QUEUE_SIZE 250
@@ -150,8 +94,10 @@
m_inputPicBuffer[pass] = X265_MALLOC(x265_picture*, m_queueSize);
for (uint32_t idx = 0; idx < m_queueSize; idx++)
{
- m_inputPicBuffer[pass][idx] = NULL;
+ m_inputPicBuffer[pass][idx] = x265_picture_alloc();
+ x265_picture_init(m_passEnc[pass]->m_param, m_inputPicBuffer[pass][idx]);
}
+
m_analysisBuffer[pass] = X265_MALLOC(x265_analysis_data, m_queueSize);
m_picIdxReadCnt[pass] = new ThreadSafeInteger[m_queueSize];
m_analysisWrite[pass] = new ThreadSafeInteger[m_queueSize];
@@ -161,32 +107,25 @@
return true;
}
- void AbrEncoder::closeEncoder()
- {
- for (uint8_t pidx = 0; pidx < m_numEncodes; pidx++)
- {
- PassEncoder *passWorker = m_passEnc[pidx];
- if (passWorker)
- passWorker->close();
- }
- }
-
void AbrEncoder::destroy()
{
- closeEncoder();
x265_cleanup(); /* Free library singletons */
for (uint8_t pass = 0; pass < m_numEncodes; pass++)
{
for (uint32_t index = 0; index < m_queueSize; index++)
{
+ X265_FREE(m_inputPicBuffer[pass][index]->planes[0]);
x265_picture_free(m_inputPicBuffer[pass][index]);
}
+
X265_FREE(m_inputPicBuffer[pass]);
X265_FREE(m_analysisBuffer[pass]);
+ X265_FREE(m_readFlag[pass]);
delete[] m_picIdxReadCnt[pass];
delete[] m_analysisWrite[pass];
delete[] m_analysisRead[pass];
m_passEnc[pass]->destroy();
+ delete m_passEnc[pass];
}
X265_FREE(m_inputPicBuffer);
X265_FREE(m_analysisBuffer);
@@ -211,13 +150,13 @@
m_parent = parent;
if(!(m_cliopt.enableScaler && m_id))
m_input = m_cliopt.input;
- m_param = x265_param_alloc();
- x265_copy_params(m_param, cliopt.param);
+ m_param = cliopt.param;
m_inputOver = false;
m_lastIdx = -1;
m_encoder = NULL;
m_scaler = NULL;
m_reader = NULL;
+ m_ret = 0;
}
int PassEncoder::init(int &result)
@@ -244,25 +183,6 @@
}
}
}
-
- if (m_cliopt.zoneFile)
- {
- if (!m_cliopt.parseZoneFile())
- {
- x265_log(NULL, X265_LOG_ERROR, "Unable to parse zonefile\n");
- fclose(m_cliopt.zoneFile);
- m_cliopt.zoneFile = NULL;
- }
- }
-
- if (m_param)
- m_encoder = m_cliopt.api->encoder_open(m_param);
- if (!m_encoder)
- {
- x265_log(NULL, X265_LOG_ERROR, "x265_encoder_open() failed for Enc, \n");
- return -1;
- }
- m_cliopt.api->encoder_parameters(m_encoder, m_param);
return 1;
}
@@ -272,15 +192,13 @@
m_param->confWinBottomOffset = m_param->confWinRightOffset = 0;
- m_isAnalysisSave = m_cliopt.saveLevel ? true : false;
- m_isAnalysisLoad = m_cliopt.loadLevel ? true : false;
m_param->analysisLoadReuseLevel = m_cliopt.loadLevel;
m_param->analysisSaveReuseLevel = m_cliopt.saveLevel;
- m_param->analysisSave = m_isAnalysisSave ? "save.dat" : NULL;
- m_param->analysisLoad = m_isAnalysisLoad ? "load.dat" : NULL;
+ m_param->analysisSave = m_cliopt.saveLevel ? "save.dat" : NULL;
+ m_param->analysisLoad = m_cliopt.loadLevel ? "load.dat" : NULL;
m_param->bUseAnalysisFile = 0;
- if (m_isAnalysisLoad)
+ if (m_cliopt.loadLevel)
{
x265_param *refParam = m_parent->m_passEnc[m_cliopt.refId]->m_param;
@@ -460,7 +378,7 @@
int ipread = m_parent->m_picReadCnt[m_id].get();
int ipwrite = m_parent->m_picWriteCnt[m_id].get();
- bool isAbrLoad = m_isAnalysisLoad && (m_parent->m_numEncodes > 1);
+ bool isAbrLoad = m_cliopt.loadLevel && (m_parent->m_numEncodes > 1);
while (!m_inputOver && (ipread == ipwrite))
{
ipwrite = m_parent->m_picWriteCnt[m_id].waitForChange(ipwrite);
@@ -561,215 +479,289 @@
void PassEncoder::threadMain()
{
+ THREAD_NAME("PassEncoder", m_id);
+
+ while (m_threadActive)
+ {
#if ENABLE_LIBVMAF
- x265_vmaf_data* vmafdata = cliopt.vmafData;
+ x265_vmaf_data* vmafdata = m_cliopt.vmafData;
#endif
- /* This allows muxers to modify bitstream format */
- m_cliopt.output->setParam(m_param);
- const x265_api* api = m_cliopt.api;
- ReconPlay* reconPlay = NULL;
- if (m_cliopt.reconPlayCmd)
- reconPlay = new ReconPlay(m_cliopt.reconPlayCmd, *m_param);
-
- if (signal(SIGINT, sigint_handler) == SIG_ERR)
- x265_log(m_param, X265_LOG_ERROR, "Unable to register CTRL+C handler: %s\n", strerror(errno));
+ /* This allows muxers to modify bitstream format */
+ m_cliopt.output->setParam(m_param);
+ const x265_api* api = m_cliopt.api;
+ ReconPlay* reconPlay = NULL;
+ if (m_cliopt.reconPlayCmd)
+ reconPlay = new ReconPlay(m_cliopt.reconPlayCmd, *m_param);
+ char* profileName = m_cliopt.encName ? m_cliopt.encName : (char *)"x265";
- x265_picture pic_orig, pic_out;
- x265_picture *pic_in = &pic_orig;
- /* Allocate recon picture if analysis save/load is enabled */
- std::priority_queue<int64_t>* pts_queue = m_cliopt.output->needPTS() ? new std::priority_queue<int64_t>() : NULL;
- x265_picture *pic_recon = (m_cliopt.recon || m_param->analysisSave || m_param->analysisLoad || pts_queue || reconPlay || m_param->csvLogLevel) ? &pic_out : NULL;
- uint32_t inFrameCount = 0;
- uint32_t outFrameCount = 0;
- x265_nal *p_nal;
- x265_stats stats;
- uint32_t nal;
- int16_t *errorBuf = NULL;
- bool bDolbyVisionRPU = false;
- uint8_t *rpuPayload = NULL;
- int inputPicNum = 1;
- x265_picture picField1, picField2;
- x265_analysis_data* analysisInfo = (x265_analysis_data*)(&pic_out.analysisData);
- bool isAbrSave = m_isAnalysisSave && (m_parent->m_numEncodes > 1);
-
- if (!m_param->bRepeatHeaders && !m_param->bEnableSvtHevc)
- {
- if (api->encoder_headers(m_encoder, &p_nal, &nal) < 0)
+ if (m_cliopt.zoneFile)
{
- x265_log(m_param, X265_LOG_ERROR, "Failure generating stream headers %d\n", m_id);
- goto fail;
- }
- else
- m_cliopt.totalbytes += m_cliopt.output->writeHeaders(p_nal, nal);
- }
-
- if (m_param->bField && m_param->interlaceMode)
- {
- api->picture_init(m_param, &picField1);
- api->picture_init(m_param, &picField2);
- // return back the original height of input
- m_param->sourceHeight *= 2;
- api->picture_init(m_param, &pic_orig);
- }
- else
- api->picture_init(m_param, &pic_orig);
-
- if (m_param->dolbyProfile && m_cliopt.dolbyVisionRpu)
- {
- rpuPayload = X265_MALLOC(uint8_t, 1024);
- pic_in->rpu.payload = rpuPayload;
- if (pic_in->rpu.payload)
- bDolbyVisionRPU = true;
- }
-
- if (m_cliopt.bDither)
- {
- errorBuf = X265_MALLOC(int16_t, m_param->sourceWidth + 1);
- if (errorBuf)
- memset(errorBuf, 0, (m_param->sourceWidth + 1) * sizeof(int16_t));
- else
- m_cliopt.bDither = false;
- }
-
- // main encoder loop
- while (pic_in && !b_ctrl_c)
- {
- pic_orig.poc = (m_param->bField && m_param->interlaceMode) ? inFrameCount * 2 : inFrameCount;
- if (m_cliopt.qpfile)
- {
- if (!m_cliopt.parseQPFile(pic_orig))
+ if (!m_cliopt.parseZoneFile())
{
- x265_log(NULL, X265_LOG_ERROR, "can't parse qpfile for frame %d\n", pic_in->poc);
- fclose(m_cliopt.qpfile);
- m_cliopt.qpfile = NULL;
+ x265_log(NULL, X265_LOG_ERROR, "Unable to parse zonefile in %s\n", profileName);
+ fclose(m_cliopt.zoneFile);
+ m_cliopt.zoneFile = NULL;
}
}
- if (m_cliopt.framesToBeEncoded && inFrameCount >= m_cliopt.framesToBeEncoded)
+ /* note: we could try to acquire a different libx265 API here based on
+ * the profile found during option parsing, but it must be done before
+ * opening an encoder */
+
+ m_encoder = api->encoder_open(m_param);
+ if (!m_encoder)
{
- pic_in = NULL;
+ x265_log(NULL, X265_LOG_ERROR, "failed to open encoder in %s\n", profileName);
+ api->param_free(m_param);
+ m_ret = 2;
+ break;
}
- else if (readPicture(pic_in))
- inFrameCount++;
- else
- pic_in = NULL;
+
+ /* get the encoder parameters post-initialization */
+ api->encoder_parameters(m_encoder, m_param);
+
+ if (signal(SIGINT, sigint_handler) == SIG_ERR)
+ x265_log(m_param, X265_LOG_ERROR, "Unable to register CTRL+C handler: %s in %s\n",
+ strerror(errno), profileName);
- if (pic_in)
+ x265_picture pic_orig, pic_out;
+ x265_picture *pic_in = &pic_orig;
+ /* Allocate recon picture if analysis save/load is enabled */
+ std::priority_queue<int64_t>* pts_queue = m_cliopt.output->needPTS() ? new std::priority_queue<int64_t>() : NULL;
+ x265_picture *pic_recon = (m_cliopt.recon || m_param->analysisSave || m_param->analysisLoad || pts_queue || reconPlay || m_param->csvLogLevel) ? &pic_out : NULL;
+ uint32_t inFrameCount = 0;
+ uint32_t outFrameCount = 0;
+ x265_nal *p_nal;
+ x265_stats stats;
+ uint32_t nal;
+ int16_t *errorBuf = NULL;
+ bool bDolbyVisionRPU = false;
+ uint8_t *rpuPayload = NULL;
+ int inputPicNum = 1;
+ x265_picture picField1, picField2;
+ x265_analysis_data* analysisInfo = (x265_analysis_data*)(&pic_out.analysisData);
+ bool isAbrSave = m_cliopt.saveLevel && (m_parent->m_numEncodes > 1);
+
+ if (!m_param->bRepeatHeaders && !m_param->bEnableSvtHevc)
{
- if (pic_in->bitDepth > m_param->internalBitDepth && m_cliopt.bDither)
+ if (api->encoder_headers(m_encoder, &p_nal, &nal) < 0)
{
- x265_dither_image(pic_in, m_cliopt.input->getWidth(), m_cliopt.input->getHeight(), errorBuf, m_param->internalBitDepth);
- pic_in->bitDepth = m_param->internalBitDepth;
+ x265_log(m_param, X265_LOG_ERROR, "Failure generating stream headers in %s\n", profileName);
+ m_ret = 3;
+ goto fail;
}
- /* Overwrite PTS */
- pic_in->pts = pic_in->poc;
+ else
+ m_cliopt.totalbytes += m_cliopt.output->writeHeaders(p_nal, nal);
+ }
+
+ if (m_param->bField && m_param->interlaceMode)
+ {
+ api->picture_init(m_param, &picField1);
+ api->picture_init(m_param, &picField2);
+ // return back the original height of input
+ m_param->sourceHeight *= 2;
+ api->picture_init(m_param, &pic_orig);
+ }
+ else
+ api->picture_init(m_param, &pic_orig);
- // convert to field
- if (m_param->bField && m_param->interlaceMode)
+ if (m_param->dolbyProfile && m_cliopt.dolbyVisionRpu)
+ {
+ rpuPayload = X265_MALLOC(uint8_t, 1024);
+ pic_in->rpu.payload = rpuPayload;
+ if (pic_in->rpu.payload)
+ bDolbyVisionRPU = true;
+ }
+
+ if (m_cliopt.bDither)
+ {
+ errorBuf = X265_MALLOC(int16_t, m_param->sourceWidth + 1);
+ if (errorBuf)
+ memset(errorBuf, 0, (m_param->sourceWidth + 1) * sizeof(int16_t));
+ else
+ m_cliopt.bDither = false;
+ }
+
+ // main encoder loop
+ while (pic_in && !b_ctrl_c)
+ {
+ pic_orig.poc = (m_param->bField && m_param->interlaceMode) ? inFrameCount * 2 : inFrameCount;
+ if (m_cliopt.qpfile)
{
- int height = pic_in->height >> 1;
-
- int static bCreated = 0;
- if (bCreated == 0)
+ if (!m_cliopt.parseQPFile(pic_orig))
{
- bCreated = 1;
- inputPicNum = 2;
- picField1.fieldNum = 1;
- picField2.fieldNum = 2;
+ x265_log(NULL, X265_LOG_ERROR, "can't parse qpfile for frame %d in %s\n",
+ pic_in->poc, profileName);
+ fclose(m_cliopt.qpfile);
+ m_cliopt.qpfile = NULL;
+ }
+ }
+
+ if (m_cliopt.framesToBeEncoded && inFrameCount >= m_cliopt.framesToBeEncoded)
+ pic_in = NULL;
+ else if (readPicture(pic_in))
+ inFrameCount++;
+ else
+ pic_in = NULL;
- picField1.bitDepth = picField2.bitDepth = pic_in->bitDepth;
- picField1.colorSpace = picField2.colorSpace = pic_in->colorSpace;
- picField1.height = picField2.height = pic_in->height >> 1;
- picField1.framesize = picField2.framesize = pic_in->framesize >> 1;
+ if (pic_in)
+ {
+ if (pic_in->bitDepth > m_param->internalBitDepth && m_cliopt.bDither)
+ {
+ x265_dither_image(pic_in, m_cliopt.input->getWidth(), m_cliopt.input->getHeight(), errorBuf, m_param->internalBitDepth);
+ pic_in->bitDepth = m_param->internalBitDepth;
+ }
+ /* Overwrite PTS */
+ pic_in->pts = pic_in->poc;
+
+ // convert to field
+ if (m_param->bField && m_param->interlaceMode)
+ {
+ int height = pic_in->height >> 1;
- size_t fieldFrameSize = (size_t)pic_in->framesize >> 1;
- char* field1Buf = X265_MALLOC(char, fieldFrameSize);
- char* field2Buf = X265_MALLOC(char, fieldFrameSize);
+ int static bCreated = 0;
+ if (bCreated == 0)
+ {
+ bCreated = 1;
+ inputPicNum = 2;
+ picField1.fieldNum = 1;
+ picField2.fieldNum = 2;
+
+ picField1.bitDepth = picField2.bitDepth = pic_in->bitDepth;
+ picField1.colorSpace = picField2.colorSpace = pic_in->colorSpace;
+ picField1.height = picField2.height = pic_in->height >> 1;
+ picField1.framesize = picField2.framesize = pic_in->framesize >> 1;
+
+ size_t fieldFrameSize = (size_t)pic_in->framesize >> 1;
+ char* field1Buf = X265_MALLOC(char, fieldFrameSize);
+ char* field2Buf = X265_MALLOC(char, fieldFrameSize);
- int stride = picField1.stride[0] = picField2.stride[0] = pic_in->stride[0];
- uint64_t framesize = stride * (height >> x265_cli_csps[pic_in->colorSpace].height[0]);
- picField1.planes[0] = field1Buf;
- picField2.planes[0] = field2Buf;
- for (int i = 1; i < x265_cli_csps[pic_in->colorSpace].planes; i++)
+ int stride = picField1.stride[0] = picField2.stride[0] = pic_in->stride[0];
+ uint64_t framesize = stride * (height >> x265_cli_csps[pic_in->colorSpace].height[0]);
+ picField1.planes[0] = field1Buf;
+ picField2.planes[0] = field2Buf;
+ for (int i = 1; i < x265_cli_csps[pic_in->colorSpace].planes; i++)
+ {
+ picField1.planes[i] = field1Buf + framesize;
+ picField2.planes[i] = field2Buf + framesize;
+
+ stride = picField1.stride[i] = picField2.stride[i] = pic_in->stride[i];
+ framesize += (stride * (height >> x265_cli_csps[pic_in->colorSpace].height[i]));
+ }
+ assert(framesize == picField1.framesize);
+ }
+
+ picField1.pts = picField1.poc = pic_in->poc;
+ picField2.pts = picField2.poc = pic_in->poc + 1;
+
+ picField1.userSEI = picField2.userSEI = pic_in->userSEI;
+
+ //if (pic_in->userData)
+ //{
+ // // Have to handle userData here
+ //}
+
+ if (pic_in->framesize)
{
- picField1.planes[i] = field1Buf + framesize;
- picField2.planes[i] = field2Buf + framesize;
+ for (int i = 0; i < x265_cli_csps[pic_in->colorSpace].planes; i++)
+ {
+ char* srcP1 = (char*)pic_in->planes[i];
+ char* srcP2 = (char*)pic_in->planes[i] + pic_in->stride[i];
+ char* p1 = (char*)picField1.planes[i];
+ char* p2 = (char*)picField2.planes[i];
+
+ int stride = picField1.stride[i];
- stride = picField1.stride[i] = picField2.stride[i] = pic_in->stride[i];
- framesize += (stride * (height >> x265_cli_csps[pic_in->colorSpace].height[i]));
+ for (int y = 0; y < (height >> x265_cli_csps[pic_in->colorSpace].height[i]); y++)
+ {
+ memcpy(p1, srcP1, stride);
+ memcpy(p2, srcP2, stride);
+ srcP1 += 2 * stride;
+ srcP2 += 2 * stride;
+ p1 += stride;
+ p2 += stride;
+ }
+ }
}
- assert(framesize == picField1.framesize);
}
- picField1.pts = picField1.poc = pic_in->poc;
- picField2.pts = picField2.poc = pic_in->poc + 1;
-
- picField1.userSEI = picField2.userSEI = pic_in->userSEI;
-
- if (pic_in->framesize)
+ if (bDolbyVisionRPU)
{
- for (int i = 0; i < x265_cli_csps[pic_in->colorSpace].planes; i++)
+ if (m_param->bField && m_param->interlaceMode)
{
- char* srcP1 = (char*)pic_in->planes[i];
- char* srcP2 = (char*)pic_in->planes[i] + pic_in->stride[i];
- char* p1 = (char*)picField1.planes[i];
- char* p2 = (char*)picField2.planes[i];
-
- int stride = picField1.stride[i];
-
- for (int y = 0; y < (height >> x265_cli_csps[pic_in->colorSpace].height[i]); y++)
- {
- memcpy(p1, srcP1, stride);
- memcpy(p2, srcP2, stride);
- srcP1 += 2 * stride;
- srcP2 += 2 * stride;
- p1 += stride;
- p2 += stride;
- }
+ if (m_cliopt.rpuParser(&picField1) > 0)
+ goto fail;
+ if (m_cliopt.rpuParser(&picField2) > 0)
+ goto fail;
+ }
+ else
+ {
+ if (m_cliopt.rpuParser(pic_in) > 0)
+ goto fail;
}
}
}
- if (bDolbyVisionRPU)
+ for (int inputNum = 0; inputNum < inputPicNum; inputNum++)
{
- if (m_param->bField && m_param->interlaceMode)
+ x265_picture *picInput = NULL;
+ if (inputPicNum == 2)
+ picInput = pic_in ? (inputNum ? &picField2 : &picField1) : NULL;
+ else
+ picInput = pic_in;
+
+ int numEncoded = api->encoder_encode(m_encoder, &p_nal, &nal, picInput, pic_recon);
+
+ int idx = (inFrameCount - 1) % m_parent->m_queueSize;
+ m_parent->m_picIdxReadCnt[m_id][idx].incr();
+ m_parent->m_picReadCnt[m_id].incr();
+ if (m_cliopt.loadLevel && picInput)
+ {
+ m_parent->m_analysisReadCnt[m_cliopt.refId].incr();
+ m_parent->m_analysisRead[m_cliopt.refId][m_lastIdx].incr();
+ }
+
+ if (numEncoded < 0)
{
- if (rpuParser(&picField1, m_cliopt.dolbyVisionRpu) > 0)
- goto fail;
- if (rpuParser(&picField2, m_cliopt.dolbyVisionRpu) > 0)
- goto fail;
+ b_ctrl_c = 1;
+ m_ret = 4;
+ break;
+ }
+
+ if (reconPlay && numEncoded)
+ reconPlay->writePicture(*pic_recon);
+
+ outFrameCount += numEncoded;
+
+ if (isAbrSave && numEncoded)
+ {
+ copyInfo(analysisInfo);
}
- else
+
+ if (numEncoded && pic_recon && m_cliopt.recon)
+ m_cliopt.recon->writePicture(pic_out);
+ if (nal)
{
- if (rpuParser(pic_in, m_cliopt.dolbyVisionRpu) > 0)
- goto fail;
+ m_cliopt.totalbytes += m_cliopt.output->writeFrame(p_nal, nal, pic_out);
+ if (pts_queue)
+ {
+ pts_queue->push(-pic_out.pts);
+ if (pts_queue->size() > 2)
+ pts_queue->pop();
+ }
}
+ m_cliopt.printStatus(outFrameCount);
}
}
- for (int inputNum = 0; inputNum < inputPicNum; inputNum++)
+ /* Flush the encoder */
+ while (!b_ctrl_c)
{
- x265_picture *picInput = NULL;
- if (inputPicNum == 2)
- picInput = pic_in ? (inputNum ? &picField2 : &picField1) : NULL;
- else
- picInput = pic_in;
-
- int numEncoded = api->encoder_encode(m_encoder, &p_nal, &nal, picInput, pic_recon);
-
- int idx = (inFrameCount - 1) % m_parent->m_queueSize;
- m_parent->m_picIdxReadCnt[m_id][idx].incr();
- m_parent->m_picReadCnt[m_id].incr();
- if (m_cliopt.loadLevel && picInput)
- {
- m_parent->m_analysisReadCnt[m_cliopt.refId].incr();
- m_parent->m_analysisRead[m_cliopt.refId][m_lastIdx].incr();
- }
-
+ int numEncoded = api->encoder_encode(m_encoder, &p_nal, &nal, NULL, pic_recon);
if (numEncoded < 0)
{
- b_ctrl_c = 1;
+ m_ret = 4;
break;
}
@@ -777,7 +769,6 @@
reconPlay->writePicture(*pic_recon);
outFrameCount += numEncoded;
-
if (isAbrSave && numEncoded)
{
copyInfo(analysisInfo);
@@ -795,106 +786,77 @@
pts_queue->pop();
}
}
+
m_cliopt.printStatus(outFrameCount);
- }
- }
- /* Flush the encoder */
- while (!b_ctrl_c)
- {
- int numEncoded = api->encoder_encode(m_encoder, &p_nal, &nal, NULL, pic_recon);
- if (numEncoded < 0)
- break;
-
- if (reconPlay && numEncoded)
- reconPlay->writePicture(*pic_recon);
-
- outFrameCount += numEncoded;
- if (isAbrSave && numEncoded)
- {
- copyInfo(analysisInfo);
+ if (!numEncoded)
+ break;
}
- if (numEncoded && pic_recon && m_cliopt.recon)
- m_cliopt.recon->writePicture(pic_out);
- if (nal)
+ if (bDolbyVisionRPU)
{
- m_cliopt.totalbytes += m_cliopt.output->writeFrame(p_nal, nal, pic_out);
- if (pts_queue)
- {
- pts_queue->push(-pic_out.pts);
- if (pts_queue->size() > 2)
- pts_queue->pop();
- }
+ if (fgetc(m_cliopt.dolbyVisionRpu) != EOF)
+ x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU count is greater than frame count in %s\n",
+ profileName);
+ x265_log(NULL, X265_LOG_INFO, "VES muxing with Dolby Vision RPU file successful in %s\n",
+ profileName);
}
- m_cliopt.printStatus(outFrameCount);
-
- if (!numEncoded)
- break;
- }
+ /* clear progress report */
+ if (m_cliopt.bProgress)
+ fprintf(stderr, "%*s\r", 80, " ");
- if (bDolbyVisionRPU)
- {
- if (fgetc(m_cliopt.dolbyVisionRpu) != EOF)
- x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU count is greater than frame count\n");
- x265_log(NULL, X265_LOG_INFO, "VES muxing with Dolby Vision RPU file successful\n");
- }
+ fail:
+
+ delete reconPlay;
- if (bDolbyVisionRPU)
- {
- if (fgetc(m_cliopt.dolbyVisionRpu) != EOF)
- x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU count is greater than frame count\n");
- x265_log(NULL, X265_LOG_INFO, "VES muxing with Dolby Vision RPU file successful\n");
- }
-
- /* clear progress report */
- if (m_cliopt.bProgress)
- fprintf(stderr, "%*s\r", 80, " ");
-
- fail:
-
- delete reconPlay;
+ api->encoder_get_stats(m_encoder, &stats, sizeof(stats));
+ if (m_param->csvfn && !b_ctrl_c)
+#if ENABLE_LIBVMAF
+ api->vmaf_encoder_log(m_encoder, m_cliopt.argCount, m_cliopt.argString, m_cliopt.param, vmafdata);
+#else
+ api->encoder_log(m_encoder, m_cliopt.argCnt, m_cliopt.argString);
+#endif
+ api->encoder_close(m_encoder);
- api->encoder_get_stats(m_encoder, &stats, sizeof(stats));
- if (m_param->csvfn && !b_ctrl_c)
-#if ENABLE_LIBVMAF
- api->vmaf_encoder_log(encoder, argc, argv, param, vmafdata);
-#else
- api->encoder_log(m_encoder, 0, NULL);
-#endif
-
- int64_t second_largest_pts = 0;
- int64_t largest_pts = 0;
-
- m_cliopt.output->closeFile(largest_pts, second_largest_pts);
+ int64_t second_largest_pts = 0;
+ int64_t largest_pts = 0;
+ if (pts_queue && pts_queue->size() >= 2)
+ {
+ second_largest_pts = -pts_queue->top();
+ pts_queue->pop();
+ largest_pts = -pts_queue->top();
+ pts_queue->pop();
+ delete pts_queue;
+ pts_queue = NULL;
+ }
+ m_cliopt.output->closeFile(largest_pts, second_largest_pts);
- if (b_ctrl_c)
- general_log(m_param, NULL, X265_LOG_INFO, "aborted at input frame %d, output frame %d\n",
- m_cliopt.seek + inFrameCount, stats.encodedPictureCount);
+ if (b_ctrl_c)
+ general_log(m_param, NULL, X265_LOG_INFO, "aborted at input frame %d, output frame %d in %s\n",
+ m_cliopt.seek + inFrameCount, stats.encodedPictureCount, profileName);
- X265_FREE(errorBuf);
- X265_FREE(rpuPayload);
+ api->param_free(m_param);
- m_threadActive = false;
- m_parent->m_numActiveEncodes.decr();
- }
+ X265_FREE(errorBuf);
+ X265_FREE(rpuPayload);
- void PassEncoder::close()
- {
- const x265_api* api = m_cliopt.api;
- api->param_free(m_param);
- api->encoder_close(m_encoder);
+ m_threadActive = false;
+ m_parent->m_numActiveEncodes.decr();
+ }
}
void PassEncoder::destroy()
{
+ stop();
if (m_reader)
{
+ m_reader->stop();
delete m_reader;
}
else
{
+ m_scaler->stop();
m_scaler->destroy();
delete m_scaler;
}
@@ -1107,12 +1069,6 @@
read = m_parentEnc->m_parent->m_picIdxReadCnt[m_id][writeIdx].waitForChange(read);
}
- if (!m_parentEnc->m_parent->m_inputPicBuffer[m_id][writeIdx])
- {
- m_parentEnc->m_parent->m_inputPicBuffer[m_id][writeIdx] = x265_picture_alloc();
- x265_picture_init(m_parentEnc->m_param, m_parentEnc->m_parent->m_inputPicBuffer[m_id][writeIdx]);
- }
-
x265_picture* dest = m_parentEnc->m_parent->m_inputPicBuffer[m_id][writeIdx];
if (m_input->readPicture(*src))
{
diff -r 94bfe7f2c0c1 -r 23da64aedc8e source/abrEncApp.h
--- a/source/abrEncApp.h Thu Apr 16 18:48:56 2020 +0530
+++ b/source/abrEncApp.h Wed Apr 15 18:44:54 2020 +0530
@@ -60,7 +60,6 @@
AbrEncoder(CLIOptions cliopt[], uint8_t numEncodes, int& ret);
bool allocBuffers();
- void closeEncoder();
void destroy();
};
@@ -75,11 +74,6 @@
x265_encoder *m_encoder;
Reader *m_reader;
Scaler *m_scaler;
-
- bool m_reqScale;
- bool m_isScaled;
- bool m_isAnalysisSave;
- bool m_isAnalysisLoad;
bool m_inputOver;
int m_threadActive;
@@ -98,7 +92,7 @@
FILE* m_zoneFile;
FILE* m_dolbyVisionRpu;/* File containing Dolby Vision BL RPU metadata */
-
+ int m_ret;
PassEncoder(uint32_t id, CLIOptions cliopt, AbrEncoder *parent);
int init(int &result);
@@ -108,7 +102,6 @@
void copyInfo(x265_analysis_data *src);
bool readPicture(x265_picture*);
- void close();
void destroy();
private:
diff -r 94bfe7f2c0c1 -r 23da64aedc8e source/x265.cpp
--- a/source/x265.cpp Thu Apr 16 18:48:56 2020 +0530
+++ b/source/x265.cpp Wed Apr 15 18:44:54 2020 +0530
@@ -29,11 +29,6 @@
#include "x265cli.h"
#include "abrEncApp.h"
-#include "input/input.h"
-#include "output/output.h"
-#include "output/reconplay.h"
-#include "svt.h"
-
#if HAVE_VLD
/* Visual Leak Detector */
#include <vld.h>
@@ -50,16 +45,12 @@
using namespace X265_NS;
+#define X265_HEAD_ENTRIES 3
+
#ifdef _WIN32
#define strdup _strdup
#endif
-/* Ctrl-C handler */
-static volatile sig_atomic_t b_ctrl_c /* = 0 */;
-
-#define START_CODE 0x00000001
-#define START_CODE_BYTES 4
-
#ifdef _WIN32
/* Copy of x264 code, which allows for Unicode characters in the command line.
* Retrieve command line arguments as UTF-8. */
@@ -97,7 +88,7 @@
* Returns true if abr-config file is present. Returns
* false otherwise */
-static bool IsAbrLadder(int argc, char **argv, FILE **abrConfig)
+static bool checkAbrLadder(int argc, char **argv, FILE **abrConfig)
{
for (optind = 0;;)
{
@@ -156,20 +147,10 @@
return numEncodes;
}
-#define X265_HEAD_ENTRIES 3
-
-static bool parseAbrConfig(FILE* abrConfig, CLIOptions cliopt[])
+static bool parseAbrConfig(FILE* abrConfig, CLIOptions cliopt[], uint8_t numEncodes)
{
char line[1024];
char* argLine;
- uint32_t numEncodes = 0;
-
- while (fgets(line, sizeof(line), abrConfig))
- {
- if (!((*line == '#') || (strcmp(line, "\r\n") == 0)))
- numEncodes++;
- }
- rewind(abrConfig);
for (uint32_t i = 0; i < numEncodes; i++)
{
@@ -182,10 +163,10 @@
argLine = line;
char* start = strchr(argLine, ' ');
while (isspace((unsigned char)*start)) start++;
- int argCount = 0;
- char **args = (char**)malloc(256 * sizeof(char *));
+ int argc = 0;
+ char **argv = (char**)malloc(256 * sizeof(char *));
// Adding a dummy string to avoid file parsing error
- args[argCount++] = (char *)"x265";
+ argv[argc++] = (char *)"x265";
/* Parse CLI header to identify the ID of the load encode and the reuse level */
char *header = strtok(argLine, "[]");
@@ -215,11 +196,11 @@
char* token = strtok(start, " ");
while (token)
{
- args[argCount++] = token;
+ argv[argc++] = token;
token = strtok(NULL, " ");
}
- args[argCount] = NULL;
- if (cliopt[i].parse(argCount, args))
+ argv[argc++] = NULL;
+ if (cliopt[i].parse(argc++, argv))
{
cliopt[i].destroy();
if (cliopt[i].api)
@@ -291,7 +272,7 @@
uint8_t numEncodes = 1;
FILE *abrConfig = NULL;
- bool isAbrLadder = IsAbrLadder(argc, argv, &abrConfig);
+ bool isAbrLadder = checkAbrLadder(argc, argv, &abrConfig);
if (isAbrLadder)
numEncodes = getNumAbrEncodes(abrConfig);
@@ -300,12 +281,12 @@
if (isAbrLadder)
{
- if(!parseAbrConfig(abrConfig, cliopt))
+ if (!parseAbrConfig(abrConfig, cliopt, numEncodes))
exit(1);
- if(!setRefContext(cliopt, numEncodes))
+ if (!setRefContext(cliopt, numEncodes))
exit(1);
}
- else if(cliopt[0].parse(argc, argv))
+ else if (cliopt[0].parse(argc, argv))
{
cliopt[0].destroy();
if (cliopt[0].api)
@@ -320,12 +301,27 @@
while (threadsActive)
{
threadsActive = abrEnc->m_numActiveEncodes.waitForChange(threadsActive);
+ for (uint8_t idx = 0; idx < numEncodes; idx++)
+ {
+ if (abrEnc->m_passEnc[idx]->m_ret)
+ {
+ if (isAbrLadder)
+ x265_log(NULL, X265_LOG_INFO, "Error generating ABR-ladder \n");
+ ret = abrEnc->m_passEnc[idx]->m_ret;
+ threadsActive = 0;
+ break;
+ }
+ }
}
abrEnc->destroy();
+ delete abrEnc;
+
for (uint8_t idx = 0; idx < numEncodes; idx++)
cliopt[idx].destroy();
+ delete[] cliopt;
+
SetConsoleTitle(orgConsoleTitle);
SetThreadExecutionState(ES_CONTINUOUS);
diff -r 94bfe7f2c0c1 -r 23da64aedc8e source/x265cli.cpp
--- a/source/x265cli.cpp Thu Apr 16 18:48:56 2020 +0530
+++ b/source/x265cli.cpp Wed Apr 15 18:44:54 2020 +0530
@@ -27,6 +27,9 @@
#include "x265cli.h"
+#define START_CODE 0x00000001
+#define START_CODE_BYTES 4
+
#ifdef __cplusplus
namespace X265_NS {
#endif
@@ -532,6 +535,8 @@
const char *tune = NULL;
const char *profile = NULL;
int svtEnabled = 0;
+ argCnt = argc;
+ argString = argv;
if (argc <= 1)
{
@@ -992,6 +997,58 @@
return 1;
}
+ /* Parse the RPU file and extract the RPU corresponding to the current picture
+ * and fill the rpu field of the input picture */
+ int CLIOptions::rpuParser(x265_picture * pic)
+ {
+ uint8_t byteVal;
+ uint32_t code = 0;
+ int bytesRead = 0;
+ pic->rpu.payloadSize = 0;
+
+ if (!pic->pts)
+ {
+ while (bytesRead++ < 4 && fread(&byteVal, sizeof(uint8_t), 1, dolbyVisionRpu))
+ code = (code << 8) | byteVal;
+
+ if (code != START_CODE)
+ {
+ x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU startcode in POC %d\n", pic->pts);
+ return 1;
+ }
+ }
+
+ bytesRead = 0;
+ while (fread(&byteVal, sizeof(uint8_t), 1, dolbyVisionRpu))
+ {
+ code = (code << 8) | byteVal;
+ if (bytesRead++ < 3)
+ continue;
+ if (bytesRead >= 1024)
+ {
+ x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU size in POC %d\n", pic->pts);
+ return 1;
+ }
+
+ if (code != START_CODE)
+ pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & 0xFF;
+ else
+ return 0;
+ }
+
+ int ShiftBytes = START_CODE_BYTES - (bytesRead - pic->rpu.payloadSize);
+ int bytesLeft = bytesRead - pic->rpu.payloadSize;
+ code = (code << ShiftBytes * 8);
+ for (int i = 0; i < bytesLeft; i++)
+ {
+ pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & 0xFF;
+ code = (code << 8);
+ }
+ if (!pic->rpu.payloadSize)
+ x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU not found for POC %d\n", pic->pts);
+ return 0;
+ }
+
#ifdef __cplusplus
}
#endif
\ No newline at end of file
diff -r 94bfe7f2c0c1 -r 23da64aedc8e source/x265cli.h
--- a/source/x265cli.h Thu Apr 16 18:48:56 2020 +0530
+++ b/source/x265cli.h Wed Apr 15 18:44:54 2020 +0530
@@ -378,7 +378,7 @@
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
- };
+};
struct CLIOptions
{
@@ -401,6 +401,9 @@
int64_t startTime;
int64_t prevUpdateTime;
+ int argCnt;
+ char** argString;
+
/* ABR ladder settings */
bool enableScaler;
char* encName;
@@ -411,7 +414,6 @@
uint32_t saveLevel;
uint32_t numRefs;
-
/* in microseconds */
static const int UPDATE_INTERVAL = 250000;
CLIOptions()
@@ -434,11 +436,14 @@
prevUpdateTime = 0;
bDither = false;
enableScaler = false;
+ encName = NULL;
+ reuseName = NULL;
encId = 0;
refId = -1;
loadLevel = 0;
saveLevel = 0;
numRefs = 0;
+ argCnt = 0;
}
void destroy();
@@ -447,6 +452,7 @@
bool parseZoneParam(int argc, char **argv, x265_param* globalParam, int zonefileCount);
bool parseQPFile(x265_picture &pic_org);
bool parseZoneFile();
+ int rpuParser(x265_picture * pic);
};
#ifdef __cplusplus
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265_push.patch
Type: text/x-patch
Size: 42802 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20200428/4cffc733/attachment-0001.bin>
More information about the x265-devel
mailing list