123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839 |
- #include <limits>
- #include <string>
- #include "absl/strings/match.h"
- #include "common_video/libyuv/include/webrtc_libyuv.h"
- #include "modules/video_coding/utility/simulcast_rate_allocator.h"
- #include "modules/video_coding/utility/simulcast_utility.h"
- #include "rtc_base/checks.h"
- #include "rtc_base/logging.h"
- #include "rtc_base/time_utils.h"
- #include "system_wrappers/include/metrics.h"
- #include "third_party/libyuv/include/libyuv/convert.h"
- #include "third_party/libyuv/include/libyuv/scale.h"
- #include "third_party/openh264/src/codec/api/svc/codec_api.h"
- #include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
- #include "third_party/openh264/src/codec/api/svc/codec_def.h"
- #include "third_party/openh264/src/codec/api/svc/codec_ver.h"
- #include "/home/nvidia/devdata/ZJ_PRO_JET/webrtcinterop/jetson_h264_encode.h"
- #include "/home/nvidia/devdata/ZJ_PRO_JET/webrtcinterop/include/NvUtils.h"
- using namespace std;
- #define IS_DIGIT(c) (c >= '0' && c <= '9')
- #define MICROSECOND_UNIT 1000000
- namespace webrtc {
- namespace {
- const bool kOpenH264EncoderDetailedLogging = false;
- static const int kLowH264QpThreshold = 24;
- static const int kHighH264QpThreshold = 37;
- enum H264EncoderImplEvent {
- kH264EncoderEventInit = 0,
- kH264EncoderEventError = 1,
- kH264EncoderEventMax = 16,
- };
- int NumberOfThreads(int width, int height, int number_of_cores) {
-
-
-
-
-
-
-
-
-
-
-
-
-
- return 1;
- }
- static void
- abort(context_enc_t *ctx)
- {
- ctx->got_error = true;
- ctx->enc->abort();
- }
- static
- Crc* InitCrc(unsigned int CrcPolynomial)
- {
- unsigned short int i;
- unsigned short int j;
- unsigned int tempcrc;
- Crc *phCrc;
- phCrc = (Crc*) malloc (sizeof(Crc));
- if (phCrc == NULL)
- {
- cerr << "Mem allocation failed for Init CRC" <<endl;
- return NULL;
- }
- memset (phCrc, 0, sizeof(Crc));
- for (i = 0; i <= 255; i++)
- {
- tempcrc = i;
- for (j = 8; j > 0; j--)
- {
- if (tempcrc & 1)
- {
- tempcrc = (tempcrc >> 1) ^ CrcPolynomial;
- }
- else
- {
- tempcrc >>= 1;
- }
- }
- phCrc->CRCTable[i] = tempcrc;
- }
- phCrc->CrcValue = 0;
- return phCrc;
- }
-
- static
- void CalculateCrc(Crc *phCrc, unsigned char *buffer, uint32_t count)
- {
- unsigned char *p;
- unsigned int temp1;
- unsigned int temp2;
- unsigned int crc = phCrc->CrcValue;
- unsigned int *CRCTable = phCrc->CRCTable;
- if(!count)
- return;
- p = (unsigned char *) buffer;
- while (count-- != 0)
- {
- temp1 = (crc >> 8) & 0x00FFFFFFL;
- temp2 = CRCTable[((unsigned int) crc ^ *p++) & 0xFF];
- crc = temp1 ^ temp2;
- }
- phCrc->CrcValue = crc;
- }
- static void *encoder_pollthread_fcn(void *arg)
- {
- context_enc_t *ctx = (context_enc_t *) arg;
- v4l2_ctrl_video_device_poll devicepoll;
- cout << "Starting Device Poll Thread " << endl;
- memset(&devicepoll, 0, sizeof(v4l2_ctrl_video_device_poll));
-
- while (!ctx->got_error && !ctx->enc->isInError())
- {
- sem_wait(&ctx->pollthread_sema);
- if (ctx->got_eos)
- {
- cout << "Got eos, exiting poll thread \n";
- return NULL;
- }
- devicepoll.req_events = POLLIN | POLLOUT | POLLERR | POLLPRI;
-
- ctx->enc->DevicePoll(&devicepoll);
-
- sem_post(&ctx->encoderthread_sema);
- }
- return NULL;
- }
- static int
- write_encoder_output_frame(ofstream * stream, NvBuffer * buffer)
- {
- stream->write((char *) buffer->planes[0].data, buffer->planes[0].bytesused);
- return 0;
- }
- static bool
- encoder_capture_plane_dq_callback(struct v4l2_buffer *v4l2_buf, NvBuffer * buffer,
- NvBuffer * shared_buffer, void *arg)
- {
- printf("------------------------------------\n");
- context_enc_t *ctx = (context_enc_t *) arg;
- NvVideoEncoder *enc = ctx->enc;
- pthread_setname_np(pthread_self(), "EncCapPlane");
- uint32_t frame_num = ctx->enc->capture_plane.getTotalDequeuedBuffers() - 1;
- uint32_t ReconRef_Y_CRC = 0;
- uint32_t ReconRef_U_CRC = 0;
- uint32_t ReconRef_V_CRC = 0;
- static uint32_t num_encoded_frames = 1;
- struct v4l2_event ev;
- int ret = 0;
- if (v4l2_buf == NULL)
- {
- cout << "Error while dequeing buffer from output plane" << endl;
- abort(ctx);
- return false;
- }
- if (ctx->b_use_enc_cmd)
- {
- if(v4l2_buf->flags & V4L2_BUF_FLAG_LAST)
- {
- memset(&ev,0,sizeof(struct v4l2_event));
- ret = ctx->enc->dqEvent(ev,1000);
- if (ret < 0)
- cout << "Error in dqEvent" << endl;
- if(ev.type == V4L2_EVENT_EOS)
- return false;
- }
- }
-
- if (buffer->planes[0].bytesused == 0)
- {
- cout << "Got 0 size buffer in capture \n";
- return false;
- }
-
- if(ctx->pBitStreamCrc)
- CalculateCrc (ctx->pBitStreamCrc, buffer->planes[0].data, buffer->planes[0].bytesused);
- if (!ctx->stats)
-
- write_encoder_output_frame(ctx->out_file, buffer);
-
- if (ctx->gdr_out_frame_number != 0xFFFFFFFF)
- if ( (ctx->enableGDR) && (ctx->GDR_out_file_path) && (num_encoded_frames >= ctx->gdr_out_frame_number+1))
- write_encoder_output_frame(ctx->gdr_out_file, buffer);
- num_encoded_frames++;
- if (ctx->report_metadata)
- {
- v4l2_ctrl_videoenc_outputbuf_metadata enc_metadata;
- if (ctx->enc->getMetadata(v4l2_buf->index, enc_metadata) == 0)
- {
- if (ctx->bReconCrc && enc_metadata.bValidReconCRC) {
-
- cout << "Frame: " << frame_num << endl;
- cout << "ReconFrame_Y_CRC " << enc_metadata.ReconFrame_Y_CRC <<
- " ReconFrame_U_CRC " << enc_metadata.ReconFrame_U_CRC <<
- " ReconFrame_V_CRC " << enc_metadata.ReconFrame_V_CRC <<
- endl;
- if (!ctx->recon_Ref_file->eof())
- {
- string recon_ref_YUV_data[4];
- parse_csv_recon_file(ctx->recon_Ref_file, recon_ref_YUV_data);
- ReconRef_Y_CRC = stoul(recon_ref_YUV_data[0]);
- ReconRef_U_CRC = stoul(recon_ref_YUV_data[1]);
- ReconRef_V_CRC = stoul(recon_ref_YUV_data[2]);
- }
- if ((ReconRef_Y_CRC != enc_metadata.ReconFrame_Y_CRC) ||
- (ReconRef_U_CRC != enc_metadata.ReconFrame_U_CRC) ||
- (ReconRef_V_CRC != enc_metadata.ReconFrame_V_CRC))
- {
- cout << "Recon CRC FAIL" << endl;
- cout << "ReconRef_Y_CRC " << ReconRef_Y_CRC <<
- " ReconRef_U_CRC " << ReconRef_U_CRC <<
- " ReconRef_V_CRC " << ReconRef_V_CRC <<
- endl;
- abort(ctx);
- return false;
- }
- cout << "Recon CRC PASS for frame : " << frame_num << endl;
- } else if (ctx->externalRPS && enc_metadata.bRPSFeedback_status) {
-
- ctx->rps_par.nActiveRefFrames = enc_metadata.nActiveRefFrames;
- cout << "Frame: " << frame_num << endl;
- cout << "nCurrentRefFrameId " << enc_metadata.nCurrentRefFrameId <<
- " nActiveRefFrames " << enc_metadata.nActiveRefFrames << endl;
- for (uint32_t i = 0; i < enc_metadata.nActiveRefFrames; i++)
- {
-
- ctx->rps_par.rps_list[i].nFrameId = enc_metadata.RPSList[i].nFrameId;
- ctx->rps_par.rps_list[i].bLTRefFrame = enc_metadata.RPSList[i].bLTRefFrame;
- cout << "FrameId " << enc_metadata.RPSList[i].nFrameId <<
- " IdrFrame " << (int) enc_metadata.RPSList[i].bIdrFrame <<
- " LTRefFrame " << (int) enc_metadata.RPSList[i].bLTRefFrame <<
- " PictureOrderCnt " << enc_metadata.RPSList[i].nPictureOrderCnt <<
- " FrameNum " << enc_metadata.RPSList[i].nFrameNum <<
- " LTFrameIdx " << enc_metadata.RPSList[i].nLTRFrameIdx << endl;
- }
- } else if (ctx->externalRCHints) {
-
- cout << "Frame: " << frame_num << endl;
- cout << "EncodedBits " << enc_metadata.EncodedFrameBits <<
- " MinQP " << enc_metadata.FrameMinQP <<
- " MaxQP " << enc_metadata.FrameMaxQP <<
- endl;
- } else {
- cout << "Frame " << frame_num <<
- ": isKeyFrame=" << (int) enc_metadata.KeyFrame <<
- " AvgQP=" << enc_metadata.AvgQP <<
- " MinQP=" << enc_metadata.FrameMinQP <<
- " MaxQP=" << enc_metadata.FrameMaxQP <<
- " EncodedBits=" << enc_metadata.EncodedFrameBits <<
- endl;
- }
- }
- }
- if (ctx->dump_mv)
- {
-
- v4l2_ctrl_videoenc_outputbuf_metadata_MV enc_mv_metadata;
- if (ctx->enc->getMotionVectors(v4l2_buf->index, enc_mv_metadata) == 0)
- {
- uint32_t numMVs = enc_mv_metadata.bufSize / sizeof(MVInfo);
- MVInfo *pInfo = enc_mv_metadata.pMVInfo;
- cout << "Frame " << frame_num << ": Num MVs=" << numMVs << endl;
- for (uint32_t i = 0; i < numMVs; i++, pInfo++)
- {
- cout << i << ": mv_x=" << pInfo->mv_x <<
- " mv_y=" << pInfo->mv_y <<
- " weight=" << pInfo->weight <<
- endl;
- }
- }
- }
- if (ctx->blocking_mode && ctx->RPS_threeLayerSvc)
- {
- sem_post(&ctx->rps_par.sema);
- }
-
- if (enc->capture_plane.qBuffer(*v4l2_buf, NULL) < 0)
- {
- cerr << "Error while Qing buffer at capture plane" << endl;
- abort(ctx);
- return false;
- }
- return true;
- }
- static int
- setup_output_dmabuf(context_enc_t *ctx, uint32_t num_buffers )
- {
- int ret=0;
- NvBufSurf::NvCommonAllocateParams cParams;
- int fd;
- ret = ctx->enc->output_plane.reqbufs(V4L2_MEMORY_DMABUF,num_buffers);
- if(ret)
- {
- cerr << "reqbufs failed for output plane V4L2_MEMORY_DMABUF" << endl;
- return ret;
- }
- for (uint32_t i = 0; i < ctx->enc->output_plane.getNumBuffers(); i++)
- {
- cParams.width = ctx->width;
- cParams.height = ctx->height;
- cParams.layout = NVBUF_LAYOUT_PITCH;
- switch (ctx->cs)
- {
- case V4L2_COLORSPACE_REC709:
- cParams.colorFormat = ctx->enable_extended_colorformat ?
- NVBUF_COLOR_FORMAT_YUV420_709_ER : NVBUF_COLOR_FORMAT_YUV420_709;
- break;
- case V4L2_COLORSPACE_SMPTE170M:
- default:
- cParams.colorFormat = ctx->enable_extended_colorformat ?
- NVBUF_COLOR_FORMAT_YUV420_ER : NVBUF_COLOR_FORMAT_YUV420;
- }
- if (ctx->is_semiplanar)
- {
- cParams.colorFormat = NVBUF_COLOR_FORMAT_NV12;
- }
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H264)
- {
- if (ctx->enableLossless)
- {
- if (ctx->is_semiplanar)
- cParams.colorFormat = NVBUF_COLOR_FORMAT_NV24;
- else
- cParams.colorFormat = NVBUF_COLOR_FORMAT_YUV444;
- }
- }
- else if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H265)
- {
- if (ctx->chroma_format_idc == 3)
- {
- if (ctx->is_semiplanar)
- cParams.colorFormat = NVBUF_COLOR_FORMAT_NV24;
- else
- cParams.colorFormat = NVBUF_COLOR_FORMAT_YUV444;
- if (ctx->bit_depth == 10)
- cParams.colorFormat = NVBUF_COLOR_FORMAT_NV24_10LE;
- }
- if (ctx->profile == V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10 && (ctx->bit_depth == 10))
- {
- cParams.colorFormat = NVBUF_COLOR_FORMAT_NV12_10LE;
- }
- }
- cParams.memtag = NvBufSurfaceTag_VIDEO_ENC;
- cParams.memType = NVBUF_MEM_SURFACE_ARRAY;
-
- ret = NvBufSurf::NvAllocate(&cParams, 1, &fd);
- if(ret < 0)
- {
- cerr << "Failed to create NvBuffer" << endl;
- return ret;
- }
- ctx->output_plane_fd[i]=fd;
- }
- return ret;
- }
- static int
- setup_capture_dmabuf(context_enc_t *ctx, uint32_t num_buffers )
- {
- NvBufSurfaceAllocateParams cParams = {{0}};
- NvBufSurface *surface = 0;
- int ret=0;
- ret = ctx->enc->capture_plane.reqbufs(V4L2_MEMORY_DMABUF,num_buffers);
- if(ret)
- {
- cerr << "reqbufs failed for capture plane V4L2_MEMORY_DMABUF" << endl;
- return ret;
- }
- for (uint32_t i = 0; i < ctx->enc->capture_plane.getNumBuffers(); i++)
- {
- ret = ctx->enc->capture_plane.queryBuffer(i);
- if (ret)
- {
- cerr << "Error in querying for " << i << "th buffer plane" << endl;
- return ret;
- }
- NvBuffer *buffer = ctx->enc->capture_plane.getNthBuffer(i);
- cParams.params.memType = NVBUF_MEM_HANDLE;
- cParams.params.size = buffer->planes[0].length;
- cParams.memtag = NvBufSurfaceTag_VIDEO_ENC;
- ret = NvBufSurfaceAllocate(&surface, 1, &cParams);
- if(ret < 0)
- {
- cerr << "Failed to create NvBuffer" << endl;
- return ret;
- }
- surface->numFilled = 1;
- ctx->capture_plane_fd[i] = surface->surfaceList[0].bufferDesc;
- }
- return ret;
- }
- static int
- get_next_parsed_pair(context_enc_t *ctx, char *id, uint32_t *value)
- {
- char charval;
- *ctx->runtime_params_str >> *id;
- if (ctx->runtime_params_str->eof())
- {
- return -1;
- }
- charval = ctx->runtime_params_str->peek();
- if (!IS_DIGIT(charval))
- {
- return -1;
- }
- *ctx->runtime_params_str >> *value;
- *ctx->runtime_params_str >> charval;
- if (ctx->runtime_params_str->eof())
- {
- return 0;
- }
- return charval;
- }
- static int
- get_next_runtime_param_change_frame(context_enc_t *ctx)
- {
- char charval;
- int ret;
- ret = get_next_parsed_pair(ctx, &charval, &ctx->next_param_change_frame);
- if(ret == 0)
- {
- return 0;
- }
-
- return 0;
- }
- VideoFrameType ConvertToVideoFrameType(EVideoFrameType type) {
- switch (type) {
- case videoFrameTypeIDR:
- return VideoFrameType::kVideoFrameKey;
- case videoFrameTypeSkip:
- case videoFrameTypeI:
- case videoFrameTypeP:
- case videoFrameTypeIPMixed:
- return VideoFrameType::kVideoFrameDelta;
- case videoFrameTypeInvalid:
- break;
- }
- RTC_NOTREACHED() << "Unexpected/invalid frame type: " << type;
- return VideoFrameType::kEmptyFrame;
- }
- }
- static void RtpFragmentize(EncodedImage* encoded_image, SFrameBSInfo* info) {
-
- size_t required_capacity = 0;
- size_t fragments_count = 0;
- for (int layer = 0; layer < info->iLayerNum; ++layer) {
- const SLayerBSInfo& layerInfo = info->sLayerInfo[layer];
- for (int nal = 0; nal < layerInfo.iNalCount; ++nal, ++fragments_count) {
- RTC_CHECK_GE(layerInfo.pNalLengthInByte[nal], 0);
-
- RTC_CHECK_LE(layerInfo.pNalLengthInByte[nal],
- std::numeric_limits<size_t>::max() - required_capacity);
- required_capacity += layerInfo.pNalLengthInByte[nal];
- }
- }
-
- auto buffer = EncodedImageBuffer::Create(required_capacity);
- encoded_image->SetEncodedData(buffer);
-
-
- const uint8_t start_code[4] = {0, 0, 0, 1};
- size_t frag = 0;
- encoded_image->set_size(0);
- for (int layer = 0; layer < info->iLayerNum; ++layer) {
- const SLayerBSInfo& layerInfo = info->sLayerInfo[layer];
-
- size_t layer_len = 0;
- for (int nal = 0; nal < layerInfo.iNalCount; ++nal, ++frag) {
-
-
- RTC_DCHECK_GE(layerInfo.pNalLengthInByte[nal], 4);
- RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 0], start_code[0]);
- RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 1], start_code[1]);
- RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 2], start_code[2]);
- RTC_DCHECK_EQ(layerInfo.pBsBuf[layer_len + 3], start_code[3]);
- layer_len += layerInfo.pNalLengthInByte[nal];
- }
-
- memcpy(buffer->data() + encoded_image->size(), layerInfo.pBsBuf, layer_len);
- encoded_image->set_size(encoded_image->size() + layer_len);
- }
- }
- JetH264Encoder::JetH264Encoder(const cricket::VideoCodec& codec)
- : packetization_mode_(H264PacketizationMode::SingleNalUnit),
- max_payload_size_(0),
- number_of_cores_(0),
- encoded_image_callback_(nullptr),
- has_reported_init_(false),
- has_reported_error_(false) {
- RTC_CHECK(absl::EqualsIgnoreCase(codec.name, cricket::kH264CodecName));
- std::string packetization_mode_string;
- if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
- &packetization_mode_string) &&
- packetization_mode_string == "1") {
- packetization_mode_ = H264PacketizationMode::NonInterleaved;
- }
- downscaled_buffers_.reserve(kMaxSimulcastStreams - 1);
- encoded_images_.reserve(kMaxSimulcastStreams);
- encoders_.reserve(kMaxSimulcastStreams);
- configurations_.reserve(kMaxSimulcastStreams);
- tl0sync_limit_.reserve(kMaxSimulcastStreams);
- }
- JetH264Encoder::~JetH264Encoder() {
- Release();
- }
- bool JetH264Encoder::OpenEncoder(context_enc_t *ctx, JetH264Encoder::LayerConfig &config)
- {
- int ret = 0;
- int error = 0;
- bool eos = false;
- memset(ctx, 0, sizeof(context_enc_t));
-
-
-
-
- ctx->encoder_pixfmt = V4L2_PIX_FMT_H264;
-
- ctx->raw_pixfmt = V4L2_PIX_FMT_YUV420M;
- ctx->bitrate = 4 * 1024 * 1024;
- ctx->peak_bitrate = 0;
- ctx->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
- ctx->ratecontrol = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
- ctx->iframe_interval = 30;
- ctx->externalRPS = false;
- ctx->enableGDR = false;
- ctx->enableROI = false;
- ctx->bnoIframe = false;
- ctx->bGapsInFrameNumAllowed = false;
- ctx->bReconCrc = false;
- ctx->enableLossless = false;
- ctx->nH264FrameNumBits = 0;
- ctx->nH265PocLsbBits = 0;
- ctx->idr_interval = 256;
- ctx->level = -1;
- ctx->fps_n = 30;
- ctx->fps_d = 1;
- ctx->gdr_start_frame_number = 0xffffffff;
- ctx->gdr_num_frames = 0xffffffff;
- ctx->gdr_out_frame_number = 0xffffffff;
- ctx->num_b_frames = (uint32_t) -1;
- ctx->nMinQpI = (uint32_t)QP_RETAIN_VAL;
- ctx->nMaxQpI = (uint32_t)QP_RETAIN_VAL;
- ctx->nMinQpP = (uint32_t)QP_RETAIN_VAL;
- ctx->nMaxQpP = (uint32_t)QP_RETAIN_VAL;
- ctx->nMinQpB = (uint32_t)QP_RETAIN_VAL;
- ctx->nMaxQpB = (uint32_t)QP_RETAIN_VAL;
- ctx->use_gold_crc = false;
- ctx->pBitStreamCrc = NULL;
- ctx->externalRCHints = false;
- ctx->input_metadata = false;
- ctx->sMaxQp = 51;
- ctx->stats = false;
- ctx->stress_test = 1;
- ctx->output_memory_type = V4L2_MEMORY_DMABUF;
- ctx->capture_memory_type = V4L2_MEMORY_MMAP;
- ctx->cs = V4L2_COLORSPACE_SMPTE170M;
- ctx->copy_timestamp = false;
- ctx->sar_width = 0;
- ctx->sar_height = 0;
- ctx->start_ts = 0;
- ctx->max_perf = 0;
- ctx->blocking_mode = 1;
- ctx->startf = 0;
- ctx->endf = 0;
- ctx->num_output_buffers = 6;
- ctx->num_frames_to_encode = -1;
- ctx->poc_type = 0;
- ctx->chroma_format_idc = -1;
- ctx->bit_depth = 8;
- ctx->is_semiplanar = false;
- ctx->enable_initQP = false;
- ctx->IinitQP = 0;
- ctx->PinitQP = 0;
- ctx->BinitQP = 0;
- ctx->enable_ratecontrol = true;
- ctx->enable_av1tile = false;
- ctx->log2_num_av1rows = 0;
- ctx->log2_num_av1cols = 0;
- ctx->enable_av1ssimrdo = (uint8_t)-1;
- ctx->disable_av1cdfupdate = (uint8_t)-1;
- ctx->ppe_init_params.enable_ppe = false;
- ctx->ppe_init_params.wait_time_ms = -1;
- ctx->ppe_init_params.feature_flags = V4L2_PPE_FEATURE_NONE;
- ctx->ppe_init_params.enable_profiler = 0;
- ctx->ppe_init_params.taq_max_qp_delta = 5;
-
- ctx->ppe_init_params.taq_b_frame_mode = 1;
-
-
-
-
-
-
-
- pthread_setname_np(pthread_self(),"EncOutPlane");
-
-
-
-
-
- if (ctx->endf) {
- ctx->num_frames_to_encode = ctx->endf - ctx->startf + 1;
- }
- if (ctx->use_gold_crc)
- {
-
- ctx->pBitStreamCrc = InitCrc(CRC32_POLYNOMIAL);
- }
-
- ctx->in_file = new ifstream(ctx->in_file_path);
- if (!ctx->stats)
- {
-
- ctx->out_file = new ofstream(ctx->out_file_path);
- }
- if (ctx->ROI_Param_file_path) {
-
- ctx->roi_Param_file = new ifstream(ctx->ROI_Param_file_path);
- }
- if (ctx->Recon_Ref_file_path) {
-
- ctx->recon_Ref_file = new ifstream(ctx->Recon_Ref_file_path);
- }
- if (ctx->RPS_Param_file_path) {
-
- ctx->rps_Param_file = new ifstream(ctx->RPS_Param_file_path);
- }
- if (ctx->GDR_Param_file_path) {
-
- ctx->gdr_Param_file = new ifstream(ctx->GDR_Param_file_path);
- }
- if (ctx->GDR_out_file_path) {
-
- ctx->gdr_out_file = new ofstream(ctx->GDR_out_file_path);
- }
- if (ctx->hints_Param_file_path) {
-
- ctx->hints_Param_file = new ifstream(ctx->hints_Param_file_path);
- }
-
-
- if (ctx->blocking_mode)
- {
- cout << "Creating Encoder in blocking mode \n";
- ctx->enc = NvVideoEncoder::createVideoEncoder("enc0");
- }
- else
- {
- cout << "Creating Encoder in non-blocking mode \n";
- ctx->enc = NvVideoEncoder::createVideoEncoder("enc0", O_NONBLOCK);
- }
- if (ctx->stats)
- {
- ctx->enc->enableProfiling();
- }
-
- ret =
- ctx->enc->setCapturePlaneFormat(ctx->encoder_pixfmt, ctx->width,
- ctx->height, 2 * 1024 * 1024);
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H265)
- {
- switch (ctx->profile)
- {
- case V4L2_MPEG_VIDEO_H265_PROFILE_MAIN10:
- {
- ctx->raw_pixfmt = V4L2_PIX_FMT_P010M;
- ctx->is_semiplanar = true;
- ctx->bit_depth = 10;
- break;
- }
- case V4L2_MPEG_VIDEO_H265_PROFILE_MAIN:
- {
- if (ctx->is_semiplanar)
- ctx->raw_pixfmt = V4L2_PIX_FMT_NV12M;
- else
- ctx->raw_pixfmt = V4L2_PIX_FMT_YUV420M;
- if (ctx->chroma_format_idc == 3)
- {
- if (ctx->bit_depth == 10 && ctx->is_semiplanar)
- ctx->raw_pixfmt = V4L2_PIX_FMT_NV24_10LE;
- if (ctx->bit_depth == 8)
- {
- if (ctx->is_semiplanar)
- ctx->raw_pixfmt = V4L2_PIX_FMT_NV24M;
- else
- ctx->raw_pixfmt = V4L2_PIX_FMT_YUV444M;
- }
- }
- }
- break;
- default:
- ctx->raw_pixfmt = V4L2_PIX_FMT_YUV420M;
- }
- }
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H264)
- {
- if (ctx->enableLossless &&
- ctx->profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE)
- {
- if (ctx->is_semiplanar)
- ctx->raw_pixfmt = V4L2_PIX_FMT_NV24M;
- else
- ctx->raw_pixfmt = V4L2_PIX_FMT_YUV444M;
- }
- else if ((ctx->enableLossless &&
- ctx->profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE) ||
- (!ctx->enableLossless && ctx->profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE))
- {
- cerr << "Lossless encoding is supported only for high444 profile\n";
- error = 1;
-
- }
- else
- {
- if (ctx->is_semiplanar)
- ctx->raw_pixfmt = V4L2_PIX_FMT_NV12M;
- else
- ctx->raw_pixfmt = V4L2_PIX_FMT_YUV420M;
- }
- }
-
- ret = ctx->enc->setOutputPlaneFormat(ctx->raw_pixfmt, ctx->width, ctx->height);
- if (ctx->num_frames_to_encode)
- {
- ret = ctx->enc->setFramesToEncode(ctx->num_frames_to_encode);
- }
- ret = ctx->enc->setBitrate(ctx->bitrate);
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H264)
- {
-
- ret = ctx->enc->setProfile(ctx->profile);
- if (ctx->level == (uint32_t)-1)
- {
- ctx->level = (uint32_t)V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
- }
- ret = ctx->enc->setLevel(ctx->level);
- }
- else if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H265)
- {
- ret = ctx->enc->setProfile(ctx->profile);
- if (ctx->level != (uint32_t)-1)
- {
- ret = ctx->enc->setLevel(ctx->level);
- }
- if (ctx->chroma_format_idc != (uint8_t)-1)
- {
- ret = ctx->enc->setChromaFactorIDC(ctx->chroma_format_idc);
- }
- }
- if (ctx->enable_initQP)
- {
- ret = ctx->enc->setInitQP(ctx->IinitQP, ctx->PinitQP, ctx->BinitQP);
- }
- if (ctx->enableLossless)
- {
- ret = ctx->enc->setLossless(ctx->enableLossless);
- }
- else if (!ctx->enable_ratecontrol)
- {
-
- ret = ctx->enc->setConstantQp(ctx->enable_ratecontrol);
- }
- else
- {
-
- ret = ctx->enc->setRateControlMode(ctx->ratecontrol);
- if (ctx->ratecontrol == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
- uint32_t peak_bitrate;
- if (ctx->peak_bitrate < ctx->bitrate)
- peak_bitrate = 1.2f * ctx->bitrate;
- else
- peak_bitrate = ctx->peak_bitrate;
-
- ret = ctx->enc->setPeakBitrate(peak_bitrate);
- }
- }
- if (ctx->poc_type)
- {
- ret = ctx->enc->setPocType(ctx->poc_type);
- }
-
- ret = ctx->enc->setIDRInterval(ctx->idr_interval);
-
- ret = ctx->enc->setIFrameInterval(ctx->iframe_interval);
-
- ret = ctx->enc->setFrameRate(ctx->fps_n, ctx->fps_d);
- if (ctx->temporal_tradeoff_level)
- {
-
- ret = ctx->enc->setTemporalTradeoff(ctx->temporal_tradeoff_level);
- }
- if (ctx->slice_length)
- {
-
- ret = ctx->enc->setSliceLength(ctx->slice_length_type,
- ctx->slice_length);
- }
- if (ctx->enable_slice_level_encode)
- {
-
- ret = ctx->enc->setSliceLevelEncode(true);
- }
- if (ctx->hw_preset_type)
- {
-
- ret = ctx->enc->setHWPresetType(ctx->hw_preset_type);
- }
- if (ctx->virtual_buffer_size)
- {
-
- ret = ctx->enc->setVirtualBufferSize(ctx->virtual_buffer_size);
- }
- if (ctx->slice_intrarefresh_interval)
- {
-
- ret = ctx->enc->setSliceIntrarefresh(ctx->slice_intrarefresh_interval);
- }
- if (ctx->insert_sps_pps_at_idr)
- {
-
- ret = ctx->enc->setInsertSpsPpsAtIdrEnabled(true);
- }
- if (ctx->disable_cabac)
- {
-
- ret = ctx->enc->setCABAC(false);
- }
- if (ctx->sar_width)
- {
-
- ret = ctx->enc->setSampleAspectRatioWidth(ctx->sar_width);
- }
- if (ctx->sar_height)
- {
-
- ret = ctx->enc->setSampleAspectRatioHeight(ctx->sar_height);
- }
- if (ctx->insert_vui)
- {
-
- ret = ctx->enc->setInsertVuiEnabled(true);
- }
- if (ctx->enable_extended_colorformat)
- {
-
- ret = ctx->enc->setExtendedColorFormat(true);
- }
- if (ctx->insert_aud)
- {
-
- ret = ctx->enc->setInsertAudEnabled(true);
- }
- if (ctx->alliframes)
- {
-
- ret = ctx->enc->setAlliFramesEncode(true);
- }
- if (ctx->num_b_frames != (uint32_t) -1)
- {
-
- ret = ctx->enc->setNumBFrames(ctx->num_b_frames);
- }
- if ((ctx->nMinQpI != (uint32_t)QP_RETAIN_VAL) ||
- (ctx->nMaxQpI != (uint32_t)QP_RETAIN_VAL) ||
- (ctx->nMinQpP != (uint32_t)QP_RETAIN_VAL) ||
- (ctx->nMaxQpP != (uint32_t)QP_RETAIN_VAL) ||
- (ctx->nMinQpB != (uint32_t)QP_RETAIN_VAL) ||
- (ctx->nMaxQpB != (uint32_t)QP_RETAIN_VAL))
- {
-
- ret = ctx->enc->setQpRange(ctx->nMinQpI, ctx->nMaxQpI, ctx->nMinQpP,
- ctx->nMaxQpP, ctx->nMinQpB, ctx->nMaxQpB);
- }
- if (ctx->max_perf)
- {
-
- ret = ctx->enc->setMaxPerfMode(ctx->max_perf);
- }
- if (ctx->dump_mv)
- {
-
- ret = ctx->enc->enableMotionVectorReporting();
- }
- if (ctx->bnoIframe) {
- ctx->iframe_interval = ((1<<31) + 1);
- ret = ctx->enc->setIFrameInterval(ctx->iframe_interval);
- }
- if (ctx->enableROI) {
- v4l2_enc_enable_roi_param VEnc_enable_ext_roi_ctrl;
- VEnc_enable_ext_roi_ctrl.bEnableROI = ctx->enableROI;
-
- ret = ctx->enc->enableROI(VEnc_enable_ext_roi_ctrl);
- }
- if (ctx->bReconCrc) {
- v4l2_enc_enable_reconcrc_param VEnc_enable_recon_crc_ctrl;
- VEnc_enable_recon_crc_ctrl.bEnableReconCRC = ctx->bReconCrc;
-
- ret = ctx->enc->enableReconCRC(VEnc_enable_recon_crc_ctrl);
- }
- if (ctx->externalRPS) {
- v4l2_enc_enable_ext_rps_ctr VEnc_enable_ext_rps_ctrl;
- VEnc_enable_ext_rps_ctrl.bEnableExternalRPS = ctx->externalRPS;
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H264) {
- VEnc_enable_ext_rps_ctrl.bGapsInFrameNumAllowed = ctx->bGapsInFrameNumAllowed;
- VEnc_enable_ext_rps_ctrl.nH264FrameNumBits = ctx->nH264FrameNumBits;
- }
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_H265) {
- VEnc_enable_ext_rps_ctrl.nH265PocLsbBits = ctx->nH265PocLsbBits;
- }
-
- ret = ctx->enc->enableExternalRPS(VEnc_enable_ext_rps_ctrl);
- }
- if (ctx->num_reference_frames)
- {
-
- ret = ctx->enc->setNumReferenceFrames(ctx->num_reference_frames);
- }
- if (ctx->externalRCHints) {
- v4l2_enc_enable_ext_rate_ctr VEnc_enable_ext_rate_ctrl;
- VEnc_enable_ext_rate_ctrl.bEnableExternalPictureRC = ctx->externalRCHints;
- VEnc_enable_ext_rate_ctrl.nsessionMaxQP = ctx->sMaxQp;
-
- ret = ctx->enc->enableExternalRC(VEnc_enable_ext_rate_ctrl);
- }
- if (ctx->encoder_pixfmt == V4L2_PIX_FMT_AV1)
- {
- if (ctx->enable_av1tile)
- {
- v4l2_enc_av1_tile_config VEnc_av1_tile_config;
- VEnc_av1_tile_config.bEnableTile = ctx->enable_av1tile;
- VEnc_av1_tile_config.nLog2RowTiles = ctx->log2_num_av1rows;
- VEnc_av1_tile_config.nLog2ColTiles = ctx->log2_num_av1cols;
-
- ret = ctx->enc->enableAV1Tile(VEnc_av1_tile_config);
- }
- if (ctx->enable_av1ssimrdo != (uint8_t) -1)
- {
- ret = ctx->enc->setAV1SsimRdo(ctx->enable_av1ssimrdo);
- }
- if (ctx->disable_av1cdfupdate != (uint8_t) -1)
- {
- ret = ctx->enc->setAV1DisableCDFUpdate(ctx->disable_av1cdfupdate);
- }
- }
-
- switch(ctx->output_memory_type)
- {
- case V4L2_MEMORY_MMAP:
- ret = ctx->enc->output_plane.setupPlane(V4L2_MEMORY_MMAP, 10, true, false);
- break;
- case V4L2_MEMORY_USERPTR:
- ret = ctx->enc->output_plane.setupPlane(V4L2_MEMORY_USERPTR, 10, false, true);
- break;
- case V4L2_MEMORY_DMABUF:
- ret = setup_output_dmabuf(ctx,10);
- break;
- default :
- break;
- }
-
- switch(ctx->capture_memory_type)
- {
- case V4L2_MEMORY_MMAP:
- ret = ctx->enc->capture_plane.setupPlane(V4L2_MEMORY_MMAP, ctx->num_output_buffers, true, false);
-
- break;
- case V4L2_MEMORY_DMABUF:
- ret = setup_capture_dmabuf(ctx,ctx->num_output_buffers);
- break;
- default :
- break;
- }
-
- ret = ctx->enc->subscribeEvent(V4L2_EVENT_EOS,0,0);
- if (ctx->b_use_enc_cmd)
- {
-
- ret = ctx->enc->setEncoderCommand(V4L2_ENC_CMD_START, 0);
- }
- else
- {
-
- ret = ctx->enc->output_plane.setStreamStatus(true);
-
- ret = ctx->enc->capture_plane.setStreamStatus(true);
- }
- if (ctx->blocking_mode)
- {
- if (ctx->RPS_threeLayerSvc)
- {
- sem_init(&ctx->rps_par.sema, 0, 0);
- }
-
- ctx->enc->capture_plane.setDQThreadCallback(encoder_capture_plane_dq_callback);
-
- ctx->enc->capture_plane.startDQThread(&ctx);
- }
- else
- {
- sem_init(&ctx->pollthread_sema, 0, 0);
- sem_init(&ctx->encoderthread_sema, 0, 0);
-
- pthread_create(&ctx->enc_pollthread, NULL, encoder_pollthread_fcn, &ctx);
- pthread_setname_np(ctx->enc_pollthread, "EncPollThread");
- cout << "Created the PollThread and Encoder Thread \n";
- }
-
-
- for (uint32_t i = 0; i < ctx->enc->capture_plane.getNumBuffers(); i++)
- {
- struct v4l2_buffer v4l2_buf;
- struct v4l2_plane planes[MAX_PLANES];
- memset(&v4l2_buf, 0, sizeof(v4l2_buf));
- memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
- v4l2_buf.index = i;
- v4l2_buf.m.planes = planes;
- if(ctx->capture_memory_type == V4L2_MEMORY_DMABUF)
- {
- v4l2_buf.m.planes[0].m.fd = ctx->capture_plane_fd[i];
-
- ret = ctx->enc->capture_plane.mapOutputBuffers(v4l2_buf, ctx->capture_plane_fd[i]);
-
-
-
-
-
-
- }
- ret = ctx->enc->capture_plane.qBuffer(v4l2_buf, NULL);
-
-
-
-
-
-
- }
- if (ctx->copy_timestamp) {
-
- ctx->timestamp = (ctx->start_ts * MICROSECOND_UNIT);
- ctx->timestampincr = (MICROSECOND_UNIT * 16) / ((uint32_t) (ctx->fps_n * 16));
- }
- if(ctx->ppe_init_params.enable_ppe)
- {
- ret = ctx->enc->setPPEInitParams(ctx->ppe_init_params);
- if (ret < 0){
- cerr << "Error calling setPPEInitParams" << endl;
- }
- }
- config.target_bps = config.max_bps;
-
- return true;
- }
- int32_t JetH264Encoder::InitEncode(const VideoCodec* inst,
- const VideoEncoder::Settings& settings) {
- printf("init ----------------------------------------\n");
- ReportInit();
- if (!inst || inst->codecType != kVideoCodecH264) {
- ReportError();
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
- }
- if (inst->maxFramerate == 0) {
- ReportError();
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
- }
- if (inst->width < 1 || inst->height < 1) {
- ReportError();
- return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
- }
- int32_t release_ret = Release();
- if (release_ret != WEBRTC_VIDEO_CODEC_OK) {
- ReportError();
- return release_ret;
- }
- int number_of_streams = SimulcastUtility::NumberOfSimulcastStreams(*inst);
- bool doing_simulcast = (number_of_streams > 1);
- if (doing_simulcast &&
- !SimulcastUtility::ValidSimulcastParameters(*inst, number_of_streams)) {
- return WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED;
- }
- downscaled_buffers_.resize(number_of_streams - 1);
- encoded_images_.resize(number_of_streams);
- encoders_.resize(number_of_streams);
- pictures_.resize(number_of_streams);
- configurations_.resize(number_of_streams);
- tl0sync_limit_.resize(number_of_streams);
- for (int i = 0; i < number_of_streams; i++){
- encoders_[i] = new context_enc_t();
- }
- number_of_cores_ = settings.number_of_cores;
- max_payload_size_ = settings.max_payload_size;
- codec_ = *inst;
-
-
- if (codec_.numberOfSimulcastStreams == 0) {
- codec_.simulcastStream[0].width = codec_.width;
- codec_.simulcastStream[0].height = codec_.height;
- }
- for (int i = 0, idx = number_of_streams - 1; i < number_of_streams;
- ++i, --idx)
- {
-
- configurations_[i].simulcast_idx = idx;
- configurations_[i].sending = false;
- configurations_[i].width = codec_.simulcastStream[idx].width;
- configurations_[i].height = codec_.simulcastStream[idx].height;
- configurations_[i].max_frame_rate = static_cast<float>(codec_.maxFramerate);
- configurations_[i].frame_dropping_on = codec_.H264()->frameDroppingOn;
- configurations_[i].key_frame_interval = codec_.H264()->keyFrameInterval;
- configurations_[i].num_temporal_layers = codec_.simulcastStream[idx].numberOfTemporalLayers;
-
- if (i > 0) {
- downscaled_buffers_[i - 1] = I420Buffer::Create(
- configurations_[i].width, configurations_[i].height,
- configurations_[i].width, configurations_[i].width / 2,
- configurations_[i].width / 2);
- }
-
- configurations_[i].max_bps = codec_.maxBitrate * 1000;
- configurations_[i].target_bps = codec_.startBitrate * 1000;
- if (!OpenEncoder(encoders_[i], configurations_[i])) {
- Release();
- ReportError();
- return WEBRTC_VIDEO_CODEC_ERROR;
- }
-
-
- const size_t new_capacity =
- CalcBufferSize(VideoType::kI420, codec_.simulcastStream[idx].width,
- codec_.simulcastStream[idx].height);
- encoded_images_[i].SetEncodedData(EncodedImageBuffer::Create(new_capacity));
- encoded_images_[i]._completeFrame = true;
- encoded_images_[i]._encodedWidth = codec_.simulcastStream[idx].width;
- encoded_images_[i]._encodedHeight = codec_.simulcastStream[idx].height;
- encoded_images_[i].set_size(0);
- tl0sync_limit_[i] = configurations_[i].num_temporal_layers;
- }
- SimulcastRateAllocator init_allocator(codec_);
- VideoBitrateAllocation allocation =
- init_allocator.Allocate(VideoBitrateAllocationParameters(
- DataRate::KilobitsPerSec(codec_.startBitrate), codec_.maxFramerate));
- return WEBRTC_VIDEO_CODEC_OK;
- }
- int32_t JetH264Encoder::RegisterEncodeCompleteCallback(
- EncodedImageCallback* callback) {
- encoded_image_callback_ = callback;
- return WEBRTC_VIDEO_CODEC_OK;
- }
- int32_t JetH264Encoder::Encode(
- const VideoFrame& input_frame,
- const std::vector<VideoFrameType>* frame_types) {
- if (encoders_.empty()) {
- ReportError();
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
- }
- if (!encoded_image_callback_) {
- RTC_LOG(LS_WARNING)
- << "InitEncode() has been called, but a callback function "
- "has not been set with RegisterEncodeCompleteCallback()";
- ReportError();
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
- }
- rtc::scoped_refptr<const I420BufferInterface> frame_buffer =
- input_frame.video_frame_buffer()->ToI420();
- bool send_key_frame = false;
- for (size_t i = 0; i < configurations_.size(); ++i) {
- if (configurations_[i].key_frame_request && configurations_[i].sending) {
- send_key_frame = true;
- break;
- }
- }
- if (!send_key_frame && frame_types) {
- for (size_t i = 0; i < configurations_.size(); ++i) {
- const size_t simulcast_idx =
- static_cast<size_t>(configurations_[i].simulcast_idx);
- if (configurations_[i].sending && simulcast_idx < frame_types->size() &&
- (*frame_types)[simulcast_idx] == VideoFrameType::kVideoFrameKey) {
- send_key_frame = true;
- break;
- }
- }
- }
- RTC_DCHECK_EQ(configurations_[0].width, frame_buffer->width());
- RTC_DCHECK_EQ(configurations_[0].height, frame_buffer->height());
-
- for (size_t i = 0; i < encoders_.size(); ++i) {
-
-
- pictures_[i] = {0};
- pictures_[i].iPicWidth = configurations_[i].width;
- pictures_[i].iPicHeight = configurations_[i].height;
- pictures_[i].iColorFormat = EVideoFormatType::videoFormatI420;
- pictures_[i].uiTimeStamp = input_frame.ntp_time_ms();
-
- if (i == 0) {
- pictures_[i].iStride[0] = frame_buffer->StrideY();
- pictures_[i].iStride[1] = frame_buffer->StrideU();
- pictures_[i].iStride[2] = frame_buffer->StrideV();
- pictures_[i].pData[0] = const_cast<uint8_t*>(frame_buffer->DataY());
- pictures_[i].pData[1] = const_cast<uint8_t*>(frame_buffer->DataU());
- pictures_[i].pData[2] = const_cast<uint8_t*>(frame_buffer->DataV());
- } else {
- pictures_[i].iStride[0] = downscaled_buffers_[i - 1]->StrideY();
- pictures_[i].iStride[1] = downscaled_buffers_[i - 1]->StrideU();
- pictures_[i].iStride[2] = downscaled_buffers_[i - 1]->StrideV();
- pictures_[i].pData[0] =
- const_cast<uint8_t*>(downscaled_buffers_[i - 1]->DataY());
- pictures_[i].pData[1] =
- const_cast<uint8_t*>(downscaled_buffers_[i - 1]->DataU());
- pictures_[i].pData[2] =
- const_cast<uint8_t*>(downscaled_buffers_[i - 1]->DataV());
-
- libyuv::I420Scale(pictures_[i - 1].pData[0], pictures_[i - 1].iStride[0],
- pictures_[i - 1].pData[1], pictures_[i - 1].iStride[1],
- pictures_[i - 1].pData[2], pictures_[i - 1].iStride[2],
- configurations_[i - 1].width,
- configurations_[i - 1].height, pictures_[i].pData[0],
- pictures_[i].iStride[0], pictures_[i].pData[1],
- pictures_[i].iStride[1], pictures_[i].pData[2],
- pictures_[i].iStride[2], configurations_[i].width,
- configurations_[i].height, libyuv::kFilterBilinear);
- }
- if (!configurations_[i].sending) {
- continue;
- }
- if (frame_types != nullptr) {
-
- if ((*frame_types)[i] == VideoFrameType::kEmptyFrame) {
- continue;
- }
- }
- if (send_key_frame) {
-
-
-
- encoders_[i]->ForceIntraFrame(true);
- configurations_[i].key_frame_request = false;
- }
-
- SFrameBSInfo info;
- memset(&info, 0, sizeof(SFrameBSInfo));
-
- int enc_ret = encoders_[i]->EncodeFrame(&pictures_[i], &info);
- if (enc_ret != 0) {
- RTC_LOG(LS_ERROR)
- << "OpenH264 frame encoding failed, EncodeFrame returned " << enc_ret
- << ".";
- ReportError();
- return WEBRTC_VIDEO_CODEC_ERROR;
- }
- encoded_images_[i]._encodedWidth = configurations_[i].width;
- encoded_images_[i]._encodedHeight = configurations_[i].height;
- encoded_images_[i].SetTimestamp(input_frame.timestamp());
- encoded_images_[i]._frameType = ConvertToVideoFrameType(info.eFrameType);
- encoded_images_[i].SetSpatialIndex(configurations_[i].simulcast_idx);
-
-
- RtpFragmentize(&encoded_images_[i], &info);
-
-
-
- if (encoded_images_[i].size() > 0) {
-
- h264_bitstream_parser_.ParseBitstream(encoded_images_[i].data(),
- encoded_images_[i].size());
- h264_bitstream_parser_.GetLastSliceQp(&encoded_images_[i].qp_);
-
- CodecSpecificInfo codec_specific;
- codec_specific.codecType = kVideoCodecH264;
- codec_specific.codecSpecific.H264.packetization_mode =
- packetization_mode_;
- codec_specific.codecSpecific.H264.temporal_idx = kNoTemporalIdx;
- codec_specific.codecSpecific.H264.idr_frame =
- info.eFrameType == videoFrameTypeIDR;
- codec_specific.codecSpecific.H264.base_layer_sync = false;
- if (configurations_[i].num_temporal_layers > 1) {
- const uint8_t tid = info.sLayerInfo[0].uiTemporalId;
- codec_specific.codecSpecific.H264.temporal_idx = tid;
- codec_specific.codecSpecific.H264.base_layer_sync =
- tid > 0 && tid < tl0sync_limit_[i];
- if (codec_specific.codecSpecific.H264.base_layer_sync) {
- tl0sync_limit_[i] = tid;
- }
- if (tid == 0) {
- tl0sync_limit_[i] = configurations_[i].num_temporal_layers;
- }
- }
- encoded_image_callback_->OnEncodedImage(encoded_images_[i],
- &codec_specific);
- }
- }
- return WEBRTC_VIDEO_CODEC_OK;
- }
- void JetH264Encoder::ReportInit() {
- if (has_reported_init_)
- return;
- RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264EncoderImpl.Event",
- kH264EncoderEventInit, kH264EncoderEventMax);
- has_reported_init_ = true;
- }
- void JetH264Encoder::ReportError() {
- if (has_reported_error_)
- return;
- RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264EncoderImpl.Event",
- kH264EncoderEventError, kH264EncoderEventMax);
- has_reported_error_ = true;
- }
- VideoEncoder::EncoderInfo JetH264Encoder::GetEncoderInfo() const {
- EncoderInfo info;
- info.supports_native_handle = false;
- info.implementation_name = "OpenH264";
- info.scaling_settings =
- VideoEncoder::ScalingSettings(kLowH264QpThreshold, kHighH264QpThreshold);
- info.is_hardware_accelerated = false;
- info.has_internal_source = false;
- info.supports_simulcast = true;
- return info;
- }
- void JetH264Encoder::LayerConfig::SetStreamState(bool send_stream) {
- if (send_stream && !sending) {
-
- key_frame_request = true;
- }
- sending = send_stream;
- }
- }
|