jetson_nv_encoder.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. #include <limits>
  2. #include <string>
  3. // WebRTC
  4. #include <common_video/libyuv/include/webrtc_libyuv.h>
  5. #include <modules/video_coding/codecs/h264/include/h264.h>
  6. #include <modules/video_coding/include/video_codec_interface.h>
  7. #include <modules/video_coding/include/video_error_codes.h>
  8. // #include <modules/video_coding/svc/create_scalability_structure.h>
  9. #include <rtc_base/checks.h>
  10. #include <rtc_base/logging.h>
  11. #include <rtc_base/time_utils.h>
  12. #include <system_wrappers/include/metrics.h>
  13. // libyuv
  14. #include <libyuv/convert.h>
  15. #include <libyuv/convert_from.h>
  16. #include <libyuv/video_common.h>
  17. // L4T Multimedia API
  18. #include "NvBufSurface.h"
  19. #include "NvVideoEncoder.h"
  20. #include "nvbufsurface.h"
  21. #include "nvbufsurftransform.h"
  22. #include "jetson_nv_encoder.h"
  23. #define H264HWENC_HEADER_DEBUG 0
  24. #define INIT_ERROR(cond, desc) \
  25. if (cond) { \
  26. RTC_LOG(LS_ERROR) << __FUNCTION__ << desc; \
  27. Release(); \
  28. return WEBRTC_VIDEO_CODEC_ERROR; \
  29. }
  30. namespace webrtc {
  31. JetsonVideoEncoder::JetsonVideoEncoder(const cricket::VideoCodec& codec)
  32. : callback_(nullptr),
  33. encoder_(nullptr),
  34. configured_framerate_(30),
  35. use_native_(false),
  36. use_dmabuff_(false) {}
  37. JetsonVideoEncoder::~JetsonVideoEncoder() {
  38. Release();
  39. }
  40. bool JetsonVideoEncoder::IsSupported(webrtc::VideoCodecType codec) {
  41. //SuppressErrors sup;
  42. auto encoder = NvVideoEncoder::createVideoEncoder("enc0");
  43. // auto ret = encoder->setCapturePlaneFormat(VideoCodecToV4L2Format(codec), 1024,
  44. // 768, 2 * 1024 * 1024);
  45. auto ret = encoder->setCapturePlaneFormat(V4L2_PIX_FMT_H264, 1280,
  46. 720, 2 * 1024 * 1024);
  47. delete encoder;
  48. return ret >= 0;
  49. }
  50. int32_t JetsonVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
  51. int32_t number_of_cores,
  52. size_t max_payload_size) {
  53. RTC_DCHECK(codec_settings);
  54. int32_t release_ret = Release();
  55. if (release_ret != WEBRTC_VIDEO_CODEC_OK) {
  56. return release_ret;
  57. }
  58. if (&codec_ != codec_settings) {
  59. codec_ = *codec_settings;
  60. }
  61. width_ = codec_settings->width;
  62. height_ = codec_settings->height;
  63. target_bitrate_bps_ = codec_settings->startBitrate * 1000;
  64. std::cout << "g=heig " << width_ << height_ << target_bitrate_bps_ << std::endl;
  65. key_frame_interval_ = codec_settings->H264().keyFrameInterval;
  66. // if (codec_settings->codecType == webrtc::kVideoCodecH264) {
  67. // key_frame_interval_ = codec_settings->H264().keyFrameInterval;
  68. // }
  69. // else if (codec_settings->codecType == webrtc::kVideoCodecH265) {
  70. // // key_frame_interval_ = codec_settings->H265().keyFrameInterval;
  71. // key_frame_interval_ = 3000;
  72. // } else if (codec_settings->codecType == webrtc::kVideoCodecVP8) {
  73. // key_frame_interval_ = codec_settings->VP8().keyFrameInterval;
  74. // } else if (codec_settings->codecType == webrtc::kVideoCodecVP9) {
  75. // key_frame_interval_ = codec_settings->VP9().keyFrameInterval;
  76. // RTC_LOG(LS_INFO) << "numberOfTemporalLayers: "
  77. // << codec_settings->VP9().numberOfTemporalLayers;
  78. // RTC_LOG(LS_INFO) << "denoisingOn: " << codec_settings->VP9().denoisingOn;
  79. // RTC_LOG(LS_INFO) << "keyFrameInterval: "
  80. // << codec_settings->VP9().keyFrameInterval;
  81. // RTC_LOG(LS_INFO) << "adaptiveQpMode: "
  82. // << codec_settings->VP9().adaptiveQpMode;
  83. // RTC_LOG(LS_INFO) << "automaticResizeOn: "
  84. // << codec_settings->VP9().automaticResizeOn;
  85. // RTC_LOG(LS_INFO) << "numberOfSpatialLayers: "
  86. // << codec_settings->VP9().numberOfSpatialLayers;
  87. // RTC_LOG(LS_INFO) << "interLayerPred: "
  88. // << codec_settings->VP9().interLayerPred;
  89. // } else if (codec_settings->codecType == webrtc::kVideoCodecAV1) {
  90. // auto scalability_mode = codec_settings->GetScalabilityMode();
  91. // if (!scalability_mode) {
  92. // RTC_LOG(LS_WARNING) << "Scalability mode is not set, using 'L1T1'.";
  93. // scalability_mode = webrtc::ScalabilityMode::kL1T1;
  94. // }
  95. // RTC_LOG(LS_INFO) << "InitEncode scalability_mode:"
  96. // << (int)*scalability_mode;
  97. // svc_controller_ = webrtc::CreateScalabilityStructure(*scalability_mode);
  98. // scalability_mode_ = *scalability_mode;
  99. // key_frame_interval_ = 3000;
  100. // }
  101. framerate_ = codec_settings->maxFramerate;
  102. RTC_LOG(LS_INFO) << "InitEncode " << framerate_ << "fps "
  103. << target_bitrate_bps_ << "bit/sec "
  104. << codec_settings->maxBitrate << "kbit/sec ";
  105. // Initialize encoded image.
  106. encoded_image_.timing_.flags =
  107. webrtc::VideoSendTiming::TimingFrameFlags::kInvalid;
  108. encoded_image_.content_type_ =
  109. (codec_settings->mode == webrtc::VideoCodecMode::kScreensharing)
  110. ? webrtc::VideoContentType::SCREENSHARE
  111. : webrtc::VideoContentType::UNSPECIFIED;
  112. gof_idx_ = 0;
  113. RTC_LOG(LS_INFO) << __FUNCTION__ << " End";
  114. return WEBRTC_VIDEO_CODEC_OK;
  115. }
  116. int32_t JetsonVideoEncoder::Release() {
  117. JetsonRelease();
  118. return WEBRTC_VIDEO_CODEC_OK;
  119. }
  120. int32_t JetsonVideoEncoder::JetsonConfigure() {
  121. int ret = 0;
  122. bool use_converter =
  123. use_native_ && (width_ != raw_width_ || height_ != raw_height_ ||
  124. decode_pixfmt_ != V4L2_PIX_FMT_YUV420M);
  125. encoder_ = NvVideoEncoder::createVideoEncoder("enc0");
  126. INIT_ERROR(!encoder_, "Failed to createVideoEncoder");
  127. // ret =
  128. // encoder_->setCapturePlaneFormat(VideoCodecToV4L2Format(codec_.codecType),
  129. // width_, height_, 2 * 1024 * 1024);
  130. ret =
  131. encoder_->setCapturePlaneFormat(V4L2_PIX_FMT_H264,
  132. width_, height_, 2 * 1024 * 1024);
  133. INIT_ERROR(ret < 0, "Failed to encoder setCapturePlaneFormat");
  134. ret = encoder_->setOutputPlaneFormat(V4L2_PIX_FMT_YUV420M, width_, height_);
  135. INIT_ERROR(ret < 0, "Failed to encoder setOutputPlaneFormat");
  136. if (codec_.codecType == webrtc::kVideoCodecH264) {
  137. printf("000000000000000000000000000000000000000000000009876542345678992534567890789657463656789065456789087654345678909456780\n");
  138. // ret = encoder_->setProfile(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
  139. ret = encoder_->setProfile(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
  140. INIT_ERROR(ret < 0, "Failed to setProfile");
  141. // ret = encoder_->setLevel(V4L2_MPEG_VIDEO_H264_LEVEL_5_1);
  142. // INIT_ERROR(ret < 0, "Failed to setLevel");
  143. ret = encoder_->setNumBFrames(0);
  144. INIT_ERROR(ret < 0, "Failed to setNumBFrames");
  145. // ret = encoder_->setInsertSpsPpsAtIdrEnabled(true);
  146. // INIT_ERROR(ret < 0, "Failed to setInsertSpsPpsAtIdrEnabled");
  147. // ret = encoder_->setInsertVuiEnabled(true);
  148. // INIT_ERROR(ret < 0, "Failed to setInsertSpsPpsAtIdrEnabled");
  149. // ret = encoder_->setHWPresetType(V4L2_ENC_HW_PRESET_FAST);
  150. // INIT_ERROR(ret < 0, "Failed to setHWPresetType");
  151. }
  152. ret = encoder_->setRateControlMode(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
  153. INIT_ERROR(ret < 0, "Failed to setRateControlMode");
  154. bitrate_adjuster_.reset(new webrtc::BitrateAdjuster(.5, .95));
  155. bitrate_adjuster_->SetTargetBitrateBps(target_bitrate_bps_);
  156. SetBitrateBps(target_bitrate_bps_);
  157. ret = encoder_->setIDRInterval(key_frame_interval_);
  158. // ret = encoder_->setIDRInterval(24);
  159. // std::cout << "key " << key_frame_interval_ << " " << framerate_ << std::endl;
  160. // ret = encoder_->setIDRInterval(256);
  161. INIT_ERROR(ret < 0, "Failed to setIDRInterval");
  162. // ret = encoder_->setIFrameInterval(0);
  163. ret = encoder_->setIFrameInterval(0);
  164. INIT_ERROR(ret < 0, "Failed to setIFrameInterval");
  165. // ret = encoder_->setFrameRate(framerate_, 1);
  166. ret = encoder_->setFrameRate(30, 1);
  167. INIT_ERROR(ret < 0, "Failed to setFrameRate");
  168. if (use_native_) {
  169. std::cout << "use native -------------------------------------------\n" << std::endl;
  170. if (use_dmabuff_ || use_converter) {
  171. std::cout << "use use_converter -------------------------------------------\n" << std::endl;
  172. ret = encoder_->output_plane.reqbufs(V4L2_MEMORY_DMABUF, 10);
  173. INIT_ERROR(ret < 0, "Failed to reqbufs at encoder output_plane");
  174. int fd;
  175. NvBufSurf::NvCommonAllocateParams cParams;
  176. cParams.width = width_;
  177. cParams.height = height_;
  178. cParams.layout = NVBUF_LAYOUT_PITCH;
  179. cParams.colorFormat = NVBUF_COLOR_FORMAT_YUV420;
  180. cParams.memtag = NvBufSurfaceTag_VIDEO_ENC;
  181. cParams.memType = NVBUF_MEM_SURFACE_ARRAY;
  182. for (uint32_t i = 0; i < encoder_->output_plane.getNumBuffers(); i++) {
  183. ret = NvBufSurf::NvAllocate(&cParams, 1, &fd);
  184. INIT_ERROR(ret, "Failed to create NvBuffer");
  185. RTC_LOG(LS_ERROR) << "NvBufferCreateEx i:" << i << " fd:" << fd;
  186. output_plane_fd_[i] = fd;
  187. }
  188. } else {
  189. ret = encoder_->output_plane.setupPlane(V4L2_MEMORY_USERPTR, 1, false,
  190. false);
  191. INIT_ERROR(ret < 0, "Failed to setupPlane at encoder output_plane");
  192. }
  193. } else {
  194. ret = encoder_->output_plane.setupPlane(V4L2_MEMORY_MMAP, 1, true, false);
  195. INIT_ERROR(ret < 0, "Failed to setupPlane at encoder output_plane");
  196. }
  197. ret = encoder_->capture_plane.setupPlane(V4L2_MEMORY_MMAP, 1, true, false);
  198. INIT_ERROR(ret < 0, "Failed to setupPlane at capture_plane");
  199. ret = encoder_->subscribeEvent(V4L2_EVENT_EOS, 0, 0);
  200. INIT_ERROR(ret < 0, "Failed to subscribeEvent V4L2_EVENT_EOS");
  201. ret = encoder_->output_plane.setStreamStatus(true);
  202. INIT_ERROR(ret < 0, "Failed to setStreamStatus at encoder output_plane");
  203. ret = encoder_->capture_plane.setStreamStatus(true);
  204. INIT_ERROR(ret < 0, "Failed to setStreamStatus at encoder capture_plane");
  205. encoder_->capture_plane.setDQThreadCallback(EncodeFinishedCallbackFunction);
  206. encoder_->capture_plane.startDQThread(this);
  207. for (uint32_t i = 0; i < encoder_->capture_plane.getNumBuffers(); i++) {
  208. struct v4l2_buffer v4l2_buf;
  209. struct v4l2_plane planes[MAX_PLANES];
  210. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  211. memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
  212. v4l2_buf.index = i;
  213. v4l2_buf.m.planes = planes;
  214. ret = encoder_->capture_plane.qBuffer(v4l2_buf, NULL);
  215. INIT_ERROR(ret < 0, "Failed to qBuffer at encoder capture_plane");
  216. }
  217. configured_framerate_ = framerate_;
  218. return WEBRTC_VIDEO_CODEC_OK;
  219. }
  220. void JetsonVideoEncoder::JetsonRelease() {
  221. if (!encoder_)
  222. return;
  223. SendEOS();
  224. encoder_->capture_plane.waitForDQThread(2000);
  225. encoder_->capture_plane.deinitPlane();
  226. if (use_dmabuff_) {
  227. for (uint32_t i = 0; i < encoder_->output_plane.getNumBuffers(); i++) {
  228. if (encoder_->output_plane.unmapOutputBuffers(i, output_plane_fd_[i]) <
  229. 0) {
  230. RTC_LOG(LS_ERROR)
  231. << "Failed to unmapOutputBuffers at encoder output_plane";
  232. }
  233. if (NvBufSurf::NvDestroy(output_plane_fd_[i]) < 0) {
  234. RTC_LOG(LS_ERROR)
  235. << "Failed to NvBufferDestroy at encoder output_plane";
  236. }
  237. }
  238. } else {
  239. encoder_->output_plane.deinitPlane();
  240. }
  241. delete encoder_;
  242. encoder_ = nullptr;
  243. }
  244. void JetsonVideoEncoder::SendEOS() {
  245. if (encoder_->output_plane.getStreamStatus()) {
  246. struct v4l2_buffer v4l2_buf;
  247. struct v4l2_plane planes[MAX_PLANES];
  248. NvBuffer* buffer;
  249. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  250. memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
  251. v4l2_buf.m.planes = planes;
  252. if (encoder_->output_plane.getNumQueuedBuffers() ==
  253. encoder_->output_plane.getNumBuffers()) {
  254. if (encoder_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 10) < 0) {
  255. RTC_LOG(LS_ERROR) << "Failed to dqBuffer at encoder output_plane";
  256. }
  257. }
  258. planes[0].bytesused = 0;
  259. for (int i = 0; i < buffer->n_planes; i++) {
  260. buffer->planes[i].bytesused = 0;
  261. }
  262. if (encoder_->output_plane.qBuffer(v4l2_buf, NULL) < 0) {
  263. RTC_LOG(LS_ERROR) << "Failed to qBuffer at encoder output_plane";
  264. }
  265. }
  266. }
  267. bool JetsonVideoEncoder::EncodeFinishedCallbackFunction(
  268. struct v4l2_buffer* v4l2_buf,
  269. NvBuffer* buffer,
  270. NvBuffer* shared_buffer,
  271. void* data) {
  272. return ((JetsonVideoEncoder*)data)
  273. ->EncodeFinishedCallback(v4l2_buf, buffer, shared_buffer);
  274. }
  275. bool JetsonVideoEncoder::EncodeFinishedCallback(struct v4l2_buffer* v4l2_buf,
  276. NvBuffer* buffer,
  277. NvBuffer* shared_buffer) {
  278. if (!v4l2_buf) {
  279. RTC_LOG(LS_INFO) << __FUNCTION__ << " v4l2_buf is null";
  280. return false;
  281. }
  282. if (buffer->planes[0].bytesused == 0) {
  283. RTC_LOG(LS_INFO) << __FUNCTION__ << " buffer size is zero";
  284. return false;
  285. }
  286. uint64_t timestamp = v4l2_buf->timestamp.tv_sec * rtc::kNumMicrosecsPerSec +
  287. v4l2_buf->timestamp.tv_usec;
  288. std::unique_ptr<FrameParams> params;
  289. {
  290. webrtc::MutexLock lock(&frame_params_lock_);
  291. do {
  292. if (frame_params_.empty()) {
  293. RTC_LOG(LS_WARNING)
  294. << __FUNCTION__
  295. << "Frame parameter is not found. SkipFrame timestamp:"
  296. << timestamp;
  297. return true;
  298. }
  299. params = std::move(frame_params_.front());
  300. frame_params_.pop();
  301. } while (params->timestamp_us < timestamp);
  302. if (params->timestamp_us != timestamp) {
  303. RTC_LOG(LS_WARNING)
  304. << __FUNCTION__
  305. << "Frame parameter is not found. SkipFrame timestamp:" << timestamp;
  306. return true;
  307. }
  308. }
  309. v4l2_ctrl_videoenc_outputbuf_metadata enc_metadata;
  310. if (encoder_->getMetadata(v4l2_buf->index, enc_metadata) != 0) {
  311. RTC_LOG(LS_WARNING) << __FUNCTION__
  312. << "getMetadata failed. SkipFrame timestamp:"
  313. << timestamp;
  314. return true;
  315. }
  316. SendFrame(buffer->planes[0].data, buffer->planes[0].bytesused,
  317. std::move(params), &enc_metadata);
  318. if (encoder_->capture_plane.qBuffer(*v4l2_buf, NULL) < 0) {
  319. RTC_LOG(LS_ERROR) << __FUNCTION__ << "Failed to qBuffer at capture_plane";
  320. return false;
  321. }
  322. return true;
  323. }
  324. int32_t JetsonVideoEncoder::RegisterEncodeCompleteCallback(
  325. webrtc::EncodedImageCallback* callback) {
  326. callback_ = callback;
  327. return WEBRTC_VIDEO_CODEC_OK;
  328. }
  329. void JetsonVideoEncoder::SetRates(const RateControlParameters& parameters) {
  330. if (encoder_ == nullptr)
  331. return;
  332. if (parameters.bitrate.get_sum_bps() <= 0 || parameters.framerate_fps <= 0)
  333. return;
  334. RTC_LOG(LS_INFO) << __FUNCTION__ << " framerate:" << parameters.framerate_fps
  335. << " bitrate:" << parameters.bitrate.ToString();
  336. // if (svc_controller_) {
  337. // svc_controller_->OnRatesUpdated(parameters.bitrate);
  338. // }
  339. framerate_ = parameters.framerate_fps;
  340. target_bitrate_bps_ = parameters.bitrate.get_sum_bps();
  341. bitrate_adjuster_->SetTargetBitrateBps(target_bitrate_bps_);
  342. return;
  343. }
  344. void JetsonVideoEncoder::SetFramerate(uint32_t framerate) {
  345. if (configured_framerate_ == framerate) {
  346. return;
  347. }
  348. RTC_LOG(LS_INFO) << __FUNCTION__ << " " << framerate << "fps";
  349. if (encoder_->setFrameRate(framerate, 1) < 0) {
  350. RTC_LOG(LS_ERROR) << "Failed to set bitrate";
  351. return;
  352. }
  353. configured_framerate_ = framerate;
  354. }
  355. void JetsonVideoEncoder::SetBitrateBps(uint32_t bitrate_bps) {
  356. if (bitrate_bps < 300000 || (configured_bitrate_bps_ == bitrate_bps &&
  357. configured_framerate_ == framerate_)) {
  358. return;
  359. }
  360. configured_bitrate_bps_ = bitrate_bps;
  361. // if (codec_.codecType == webrtc::kVideoCodecVP9) {
  362. // auto adjusted_bps = bitrate_bps * 60 / configured_framerate_;
  363. // RTC_LOG(LS_INFO) << __FUNCTION__ << " bps=" << bitrate_bps
  364. // << " adjusted_bps=" << adjusted_bps;
  365. // bitrate_bps = adjusted_bps;
  366. // } else {
  367. // RTC_LOG(LS_INFO) << __FUNCTION__ << " bps=" << bitrate_bps;
  368. // }
  369. if (encoder_->setBitrate(bitrate_bps) < 0) {
  370. RTC_LOG(LS_ERROR) << "Failed to setBitrate";
  371. return;
  372. }
  373. }
  374. webrtc::VideoEncoder::EncoderInfo JetsonVideoEncoder::GetEncoderInfo() const {
  375. printf("GET ENCODER INFO -----------------------------------------\n");
  376. EncoderInfo info;
  377. info.supports_native_handle = true;
  378. info.implementation_name = "Jetson Video Encoder";
  379. // if (codec_.codecType == webrtc::kVideoCodecH264) {
  380. // static const int kLowH264QpThreshold = 34;
  381. // static const int kHighH264QpThreshold = 40;
  382. static const int kLowH264QpThreshold = 24;
  383. static const int kHighH264QpThreshold = 37;
  384. info.scaling_settings = VideoEncoder::ScalingSettings(kLowH264QpThreshold,
  385. kHighH264QpThreshold);
  386. // } else if (codec_.codecType == webrtc::kVideoCodecH265) {
  387. // static const int kLowH265QpThreshold = 34;
  388. // static const int kHighH265QpThreshold = 40;
  389. // info.scaling_settings = VideoEncoder::ScalingSettings(kLowH265QpThreshold,
  390. // kHighH265QpThreshold);
  391. // }
  392. // else if (codec_.codecType == webrtc::kVideoCodecVP8) {
  393. // static const int kLowVp8QpThreshold = 29;
  394. // static const int kHighVp8QpThreshold = 95;
  395. // info.scaling_settings =
  396. // VideoEncoder::ScalingSettings(kLowVp8QpThreshold, kHighVp8QpThreshold);
  397. // } else if (codec_.codecType == webrtc::kVideoCodecVP9) {
  398. // static const int kLowVp9QpThreshold = 150;
  399. // static const int kHighVp9QpThreshold = 151;
  400. // info.scaling_settings =
  401. // VideoEncoder::ScalingSettings(kLowVp9QpThreshold, kHighVp9QpThreshold);
  402. // } else if (codec_.codecType == webrtc::kVideoCodecAV1) {
  403. // static const int kLowAv1QpThreshold = 145;
  404. // static const int kHighAv1QpThreshold = 205;
  405. // info.scaling_settings =
  406. // VideoEncoder::ScalingSettings(kLowAv1QpThreshold, kHighAv1QpThreshold);
  407. // }
  408. return info;
  409. }
  410. int32_t JetsonVideoEncoder::Encode(
  411. const webrtc::VideoFrame& input_frame,
  412. const std::vector<webrtc::VideoFrameType>* frame_types) {
  413. if (!callback_) {
  414. RTC_LOG(LS_WARNING)
  415. << "InitEncode() has been called, but a callback function "
  416. << "has not been set with RegisterEncodeCompleteCallback()";
  417. return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  418. }
  419. int fd = 0;
  420. webrtc::VideoType video_type;
  421. uint8_t* native_data;
  422. rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer =
  423. input_frame.video_frame_buffer();
  424. // std::shared_ptr<JetsonJpegDecoder> decoder;
  425. if (frame_buffer->type() == webrtc::VideoFrameBuffer::Type::kNative) {
  426. use_native_ = true;
  427. // JetsonBuffer* jetson_buffer =
  428. // static_cast<JetsonBuffer*>(frame_buffer.get());
  429. // video_type = jetson_buffer->VideoType();
  430. // raw_width_ = jetson_buffer->RawWidth();
  431. // raw_height_ = jetson_buffer->RawHeight();
  432. // use_dmabuff_ = true;
  433. // fd = jetson_buffer->DecodedFd();
  434. // decode_pixfmt_ = jetson_buffer->V4L2PixelFormat();
  435. // decoder = jetson_buffer->JpegDecoder();
  436. } else {
  437. use_native_ = false;
  438. }
  439. if (encoder_ == nullptr) {
  440. if (JetsonConfigure() != WEBRTC_VIDEO_CODEC_OK) {
  441. RTC_LOG(LS_ERROR) << "Failed to JetsonConfigure";
  442. return WEBRTC_VIDEO_CODEC_ERROR;
  443. }
  444. }
  445. bool force_key_frame = false;
  446. if (frame_types != nullptr) {
  447. RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1));
  448. if ((*frame_types)[0] == webrtc::VideoFrameType::kEmptyFrame) {
  449. return WEBRTC_VIDEO_CODEC_OK;
  450. }
  451. if ((*frame_types)[0] == webrtc::VideoFrameType::kVideoFrameKey) {
  452. if (encoder_->forceIDR() < 0) {
  453. RTC_LOG(LS_ERROR) << "Failed to forceIDR";
  454. }
  455. }
  456. }
  457. SetFramerate(framerate_);
  458. SetBitrateBps(bitrate_adjuster_->GetAdjustedBitrateBps());
  459. {
  460. webrtc::MutexLock lock(&frame_params_lock_);
  461. frame_params_.push(absl::make_unique<FrameParams>(
  462. frame_buffer->width(), frame_buffer->height(),
  463. input_frame.render_time_ms(), input_frame.ntp_time_ms(),
  464. input_frame.timestamp_us(), input_frame.timestamp(),
  465. // input_frame.rotation(), input_frame.color_space(), decoder));
  466. input_frame.rotation(), input_frame.color_space()));
  467. }
  468. struct v4l2_buffer v4l2_buf;
  469. struct v4l2_plane planes[MAX_PLANES];
  470. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  471. memset(planes, 0, sizeof(planes));
  472. v4l2_buf.m.planes = planes;
  473. if (use_native_) {
  474. NvBuffer* buffer;
  475. if (encoder_->output_plane.getNumQueuedBuffers() ==
  476. encoder_->output_plane.getNumBuffers()) {
  477. if (encoder_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 10) < 0) {
  478. RTC_LOG(LS_ERROR) << "Failed to dqBuffer at encoder output_plane";
  479. return WEBRTC_VIDEO_CODEC_ERROR;
  480. }
  481. } else {
  482. buffer = encoder_->output_plane.getNthBuffer(
  483. encoder_->output_plane.getNumQueuedBuffers());
  484. v4l2_buf.index = encoder_->output_plane.getNumQueuedBuffers();
  485. }
  486. int src_dma_fd = -1;
  487. if (use_dmabuff_) {
  488. src_dma_fd = fd;
  489. } else if (video_type == webrtc::VideoType::kYUY2 ||
  490. video_type == webrtc::VideoType::kUYVY) {
  491. buffer->planes[0].bytesused = buffer->planes[0].fmt.width *
  492. buffer->planes[0].fmt.bytesperpixel *
  493. buffer->planes[0].fmt.height;
  494. buffer->planes[0].data = native_data;
  495. } else if (video_type == webrtc::VideoType::kI420) {
  496. size_t offset = 0;
  497. for (int i = 0; i < buffer->n_planes; i++) {
  498. buffer->planes[i].bytesused = buffer->planes[i].fmt.width *
  499. buffer->planes[i].fmt.bytesperpixel *
  500. buffer->planes[i].fmt.height;
  501. buffer->planes[i].data = native_data + offset;
  502. offset += buffer->planes[i].bytesused;
  503. }
  504. } else if (video_type == webrtc::VideoType::kYV12) {
  505. size_t offset = 0;
  506. buffer->planes[0].bytesused = buffer->planes[0].fmt.width *
  507. buffer->planes[0].fmt.bytesperpixel *
  508. buffer->planes[0].fmt.height;
  509. buffer->planes[0].data = native_data;
  510. offset += buffer->planes[0].bytesused;
  511. buffer->planes[2].bytesused = buffer->planes[1].fmt.width *
  512. buffer->planes[1].fmt.bytesperpixel *
  513. buffer->planes[1].fmt.height;
  514. buffer->planes[2].data = native_data + offset;
  515. offset += buffer->planes[2].bytesused;
  516. buffer->planes[1].bytesused = buffer->planes[2].fmt.width *
  517. buffer->planes[2].fmt.bytesperpixel *
  518. buffer->planes[2].fmt.height;
  519. buffer->planes[1].data = native_data + offset;
  520. } else {
  521. RTC_LOG(LS_ERROR) << "Unsupported webrtc::VideoType";
  522. return WEBRTC_VIDEO_CODEC_ERROR;
  523. }
  524. NvBufSurf::NvCommonTransformParams transform_params;
  525. /* Indicates which of the transform parameters are valid */
  526. memset(&transform_params, 0, sizeof(transform_params));
  527. transform_params.src_top = 0;
  528. transform_params.src_left = 0;
  529. transform_params.src_width = raw_width_;
  530. transform_params.src_height = raw_height_;
  531. transform_params.dst_top = 0;
  532. transform_params.dst_left = 0;
  533. transform_params.dst_width = width_;
  534. transform_params.dst_height = height_;
  535. transform_params.flag =
  536. (NvBufSurfTransform_Transform_Flag)(NVBUFSURF_TRANSFORM_FILTER |
  537. NVBUFSURF_TRANSFORM_CROP_SRC);
  538. transform_params.flip = NvBufSurfTransform_None;
  539. transform_params.filter = NvBufSurfTransformInter_Bilinear;
  540. if (NvBufSurf::NvTransform(&transform_params, src_dma_fd,
  541. output_plane_fd_[v4l2_buf.index])) {
  542. RTC_LOG(LS_ERROR) << "Failed to NvBufferTransform";
  543. return WEBRTC_VIDEO_CODEC_ERROR;
  544. }
  545. planes[0].m.fd = output_plane_fd_[v4l2_buf.index];
  546. planes[0].bytesused = 1234;
  547. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
  548. v4l2_buf.memory = V4L2_MEMORY_DMABUF;
  549. v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  550. v4l2_buf.timestamp.tv_sec =
  551. input_frame.timestamp_us() / rtc::kNumMicrosecsPerSec;
  552. v4l2_buf.timestamp.tv_usec =
  553. input_frame.timestamp_us() % rtc::kNumMicrosecsPerSec;
  554. if (encoder_->output_plane.qBuffer(v4l2_buf, nullptr) < 0) {
  555. RTC_LOG(LS_ERROR) << "Failed to qBuffer at converter output_plane";
  556. return WEBRTC_VIDEO_CODEC_ERROR;
  557. }
  558. } else {
  559. NvBuffer* buffer;
  560. RTC_LOG(LS_VERBOSE) << __FUNCTION__ << " output_plane.getNumBuffers: "
  561. << encoder_->output_plane.getNumBuffers()
  562. << " output_plane.getNumQueuedBuffers: "
  563. << encoder_->output_plane.getNumQueuedBuffers();
  564. if (encoder_->output_plane.getNumQueuedBuffers() ==
  565. encoder_->output_plane.getNumBuffers()) {
  566. if (encoder_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 10) < 0) {
  567. RTC_LOG(LS_ERROR) << "Failed to dqBuffer at encoder output_plane";
  568. return WEBRTC_VIDEO_CODEC_ERROR;
  569. }
  570. } else {
  571. buffer = encoder_->output_plane.getNthBuffer(
  572. encoder_->output_plane.getNumQueuedBuffers());
  573. v4l2_buf.index = encoder_->output_plane.getNumQueuedBuffers();
  574. }
  575. rtc::scoped_refptr<const webrtc::I420BufferInterface> i420_buffer =
  576. frame_buffer->ToI420();
  577. for (uint32_t i = 0; i < buffer->n_planes; i++) {
  578. const uint8_t* source_data;
  579. int source_stride;
  580. if (i == 0) {
  581. source_data = i420_buffer->DataY();
  582. source_stride = i420_buffer->StrideY();
  583. } else if (i == 1) {
  584. source_data = i420_buffer->DataU();
  585. source_stride = i420_buffer->StrideU();
  586. } else if (i == 2) {
  587. source_data = i420_buffer->DataV();
  588. source_stride = i420_buffer->StrideV();
  589. } else {
  590. break;
  591. }
  592. NvBuffer::NvBufferPlane& plane = buffer->planes[i];
  593. std::streamsize bytes_to_read = plane.fmt.bytesperpixel * plane.fmt.width;
  594. uint8_t* input_data = plane.data;
  595. plane.bytesused = 0;
  596. for (uint32_t j = 0; j < plane.fmt.height; j++) {
  597. memcpy(input_data, source_data + (source_stride * j), bytes_to_read);
  598. input_data += plane.fmt.stride;
  599. }
  600. plane.bytesused = plane.fmt.stride * plane.fmt.height;
  601. }
  602. v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  603. v4l2_buf.timestamp.tv_sec =
  604. input_frame.timestamp_us() / rtc::kNumMicrosecsPerSec;
  605. v4l2_buf.timestamp.tv_usec =
  606. input_frame.timestamp_us() % rtc::kNumMicrosecsPerSec;
  607. for (int i = 0; i < MAX_PLANES; i++) {
  608. NvBufSurface* surf = 0;
  609. if (NvBufSurfaceFromFd(buffer->planes[i].fd, (void**)(&surf)) == -1) {
  610. RTC_LOG(LS_ERROR) << __FUNCTION__ << "Failed to NvBufSurfaceFromFd";
  611. return WEBRTC_VIDEO_CODEC_ERROR;
  612. }
  613. if (NvBufSurfaceSyncForDevice(surf, 0, i) == -1) {
  614. RTC_LOG(LS_ERROR) << "Failed to NvBufSurfaceSyncForDevice";
  615. return WEBRTC_VIDEO_CODEC_ERROR;
  616. }
  617. }
  618. if (encoder_->output_plane.qBuffer(v4l2_buf, nullptr) < 0) {
  619. RTC_LOG(LS_ERROR) << "Failed to qBuffer at encoder output_plane";
  620. return WEBRTC_VIDEO_CODEC_ERROR;
  621. }
  622. }
  623. return WEBRTC_VIDEO_CODEC_OK;
  624. }
  625. int32_t JetsonVideoEncoder::SendFrame(
  626. unsigned char* buffer,
  627. size_t size,
  628. std::unique_ptr<FrameParams> params,
  629. v4l2_ctrl_videoenc_outputbuf_metadata* enc_metadata) {
  630. if (!callback_) {
  631. RTC_LOG(LS_WARNING)
  632. << "InitEncode() has been called, but a callback function "
  633. << "has not been set with RegisterEncodeCompleteCallback()";
  634. return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  635. }
  636. // encoded_image_.SetRtpTimestamp(params->timestamp_rtp);
  637. encoded_image_.SetTimestamp(params->timestamp_rtp);
  638. encoded_image_.SetColorSpace(params->color_space);
  639. encoded_image_._encodedWidth = params->width;
  640. encoded_image_._encodedHeight = params->height;
  641. encoded_image_.capture_time_ms_ = params->render_time_ms;
  642. encoded_image_.ntp_time_ms_ = params->ntp_time_ms;
  643. encoded_image_.rotation_ = params->rotation;
  644. encoded_image_.qp_ = enc_metadata->AvgQP;
  645. // if (enc_metadata->KeyFrame) {
  646. // encoded_image_.SetFrameType(webrtc::VideoFrameType::kVideoFrameKey);
  647. // } else {
  648. // encoded_image_.SetFrameType(webrtc::VideoFrameType::kVideoFrameDelta);
  649. // }
  650. webrtc::CodecSpecificInfo codec_specific;
  651. codec_specific.codecType = codec_.codecType;
  652. // if (codec_.codecType == webrtc::kVideoCodecH264) {
  653. auto encoded_image_buffer =
  654. webrtc::EncodedImageBuffer::Create(buffer, size);
  655. encoded_image_.SetEncodedData(encoded_image_buffer);
  656. codec_specific.codecSpecific.H264.packetization_mode =
  657. webrtc::H264PacketizationMode::NonInterleaved;
  658. // }
  659. // else if (codec_.codecType == webrtc::kVideoCodecH265) {
  660. // auto encoded_image_buffer =
  661. // webrtc::EncodedImageBuffer::Create(buffer, size);
  662. // encoded_image_.SetEncodedData(encoded_image_buffer);
  663. // }
  664. RTC_LOG(LS_VERBOSE) << "key_frame=" << enc_metadata->KeyFrame
  665. << " size=" << size << " qp=" << encoded_image_.qp_;
  666. webrtc::EncodedImageCallback::Result result =
  667. callback_->OnEncodedImage(encoded_image_, &codec_specific);
  668. if (result.error != webrtc::EncodedImageCallback::Result::OK) {
  669. RTC_LOG(LS_ERROR) << __FUNCTION__
  670. << " OnEncodedImage failed error:" << result.error;
  671. return WEBRTC_VIDEO_CODEC_ERROR;
  672. }
  673. bitrate_adjuster_->Update(size);
  674. return WEBRTC_VIDEO_CODEC_OK;
  675. }
  676. } // namespace webrtc