Looks good to me overall. One suggestion - since encoder open is now a part of threadMain, can we also move the cliopt parse to threadMain?
On Tue, Apr 28, 2020 at 3:23 PM Aruna Matheswaran < ar...@multicorewareinc.com> wrote: > # HG changeset patch > # User Aruna Matheswaran <ar...@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 > } > _______________________________________________ > x265-devel mailing list > x265-devel@videolan.org > https://mailman.videolan.org/listinfo/x265-devel > -- Regards, Kavitha
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel