jetson_nv_encoder.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /*
  2. * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. *
  10. */
  11. #include "jetson_nv_encoder.h"
  12. #include <limits>
  13. #include <string>
  14. // WebRTC
  15. #include <common_video/libyuv/include/webrtc_libyuv.h>
  16. #include <modules/video_coding/codecs/h264/include/h264.h>
  17. #include <modules/video_coding/include/video_codec_interface.h>
  18. #include <modules/video_coding/include/video_error_codes.h>
  19. // #include <modules/video_coding/svc/create_scalability_structure.h>
  20. #include </home/nvidia/devdata/ZJ_PRO_DMF_JETSON_shengji/thirdparty/webrtc/include/modules/video_coding/codecs/av1/create_scalability_structure.h>
  21. #include <rtc_base/checks.h>
  22. #include <rtc_base/logging.h>
  23. #include <rtc_base/time_utils.h>
  24. #include <system_wrappers/include/metrics.h>
  25. // libyuv
  26. #include <libyuv/convert.h>
  27. #include <libyuv/convert_from.h>
  28. #include <libyuv/video_common.h>
  29. // L4T Multimedia API
  30. #include <NvBufSurface.h>
  31. #include <NvVideoEncoder.h>
  32. #include <nvbufsurface.h>
  33. // #include "jetson_util.h"
  34. // #include "jetson_buffer.h"
  35. #define H264HWENC_HEADER_DEBUG 0
  36. #define INIT_ERROR(cond, desc) \
  37. if (cond) { \
  38. RTC_LOG(LS_ERROR) << __FUNCTION__ << desc; \
  39. Release(); \
  40. return WEBRTC_VIDEO_CODEC_ERROR; \
  41. }
  42. // static std::string hex_dump(const uint8_t* buf, size_t len) {
  43. // std::stringstream ss;
  44. // for (size_t i = 0; i < len; ++i) {
  45. // if (i % 16 == 0) {
  46. // ss << std::setw(8) << std::setfill('0') << std::hex << i << ": ";
  47. // }
  48. // ss << std::setw(2) << std::setfill('0') << std::hex << (int)buf[i] << " ";
  49. // // 16バイトごとに改行
  50. // if ((i + 1) % 16 == 0 || i == len - 1) {
  51. // ss << "\n";
  52. // }
  53. // }
  54. // return ss.str();
  55. // }
  56. static void save_to_file(const std::string& filename,
  57. const uint8_t* buf,
  58. size_t size) {
  59. std::ofstream file(filename, std::ios::binary);
  60. file.write((const char*)buf, size);
  61. }
  62. namespace sora {
  63. JetsonVideoEncoder::JetsonVideoEncoder(const cricket::VideoCodec& codec)
  64. : callback_(nullptr),
  65. encoder_(nullptr),
  66. configured_framerate_(30),
  67. use_native_(true),
  68. use_dmabuff_(true) {}
  69. JetsonVideoEncoder::~JetsonVideoEncoder() {
  70. Release();
  71. }
  72. bool JetsonVideoEncoder::IsSupported(webrtc::VideoCodecType codec) {
  73. //SuppressErrors sup;
  74. auto encoder = NvVideoEncoder::createVideoEncoder("enc0");
  75. auto ret = encoder->setCapturePlaneFormat(V4L2_PIX_FMT_H264, 1024,
  76. 768, 2 * 1024 * 1024);
  77. delete encoder;
  78. return ret >= 0;
  79. }
  80. int32_t JetsonVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
  81. int32_t number_of_cores,
  82. size_t max_payload_size) {
  83. RTC_DCHECK(codec_settings);
  84. int32_t release_ret = Release();
  85. if (release_ret != WEBRTC_VIDEO_CODEC_OK) {
  86. return release_ret;
  87. }
  88. if (&codec_ != codec_settings) {
  89. codec_ = *codec_settings;
  90. }
  91. width_ = codec_settings->width;
  92. height_ = codec_settings->height;
  93. target_bitrate_bps_ = codec_settings->startBitrate * 1000;
  94. key_frame_interval_ = codec_settings->H264().keyFrameInterval;
  95. framerate_ = codec_settings->maxFramerate;
  96. RTC_LOG(LS_INFO) << "InitEncode " << framerate_ << "fps "
  97. << target_bitrate_bps_ << "bit/sec "
  98. << codec_settings->maxBitrate << "kbit/sec ";
  99. // Initialize encoded image.
  100. encoded_image_.timing_.flags =
  101. webrtc::VideoSendTiming::TimingFrameFlags::kInvalid;
  102. encoded_image_.content_type_ =
  103. (codec_settings->mode == webrtc::VideoCodecMode::kScreensharing)
  104. ? webrtc::VideoContentType::SCREENSHARE
  105. : webrtc::VideoContentType::UNSPECIFIED;
  106. gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1);
  107. gof_idx_ = 0;
  108. RTC_LOG(LS_INFO) << __FUNCTION__ << " End";
  109. return WEBRTC_VIDEO_CODEC_OK;
  110. }
  111. int32_t JetsonVideoEncoder::Release() {
  112. JetsonRelease();
  113. return WEBRTC_VIDEO_CODEC_OK;
  114. }
  115. int32_t JetsonVideoEncoder::JetsonConfigure() {
  116. int ret = 0;
  117. bool use_converter =
  118. use_native_ && (width_ != raw_width_ || height_ != raw_height_ ||
  119. decode_pixfmt_ != V4L2_PIX_FMT_YUV420M);
  120. encoder_ = NvVideoEncoder::createVideoEncoder("enc0");
  121. INIT_ERROR(!encoder_, "Failed to createVideoEncoder");
  122. ret =
  123. encoder_->setCapturePlaneFormat(V4L2_PIX_FMT_H264,
  124. width_, height_, 2 * 1024 * 1024);
  125. INIT_ERROR(ret < 0, "Failed to encoder setCapturePlaneFormat");
  126. ret = encoder_->setOutputPlaneFormat(V4L2_PIX_FMT_YUV420M, width_, height_);
  127. INIT_ERROR(ret < 0, "Failed to encoder setOutputPlaneFormat");
  128. // ret = encoder_->setProfile(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
  129. ret = encoder_->setProfile(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
  130. INIT_ERROR(ret < 0, "Failed to setProfile");
  131. ret = encoder_->setLevel(V4L2_MPEG_VIDEO_H264_LEVEL_5_1);
  132. INIT_ERROR(ret < 0, "Failed to setLevel");
  133. // 必須 なければ H264 でフレームレートが出ない
  134. ret = encoder_->setNumBFrames(0);
  135. INIT_ERROR(ret < 0, "Failed to setNumBFrames");
  136. ret = encoder_->setInsertSpsPpsAtIdrEnabled(true);
  137. INIT_ERROR(ret < 0, "Failed to setInsertSpsPpsAtIdrEnabled");
  138. ret = encoder_->setInsertVuiEnabled(true);
  139. INIT_ERROR(ret < 0, "Failed to setInsertSpsPpsAtIdrEnabled");
  140. // V4L2_ENC_HW_PRESET_ULTRAFAST が推奨値だけど MEDIUM でも Nano, AGX では OK
  141. // NX は V4L2_ENC_HW_PRESET_FAST でないとフレームレートがでない
  142. ret = encoder_->setHWPresetType(V4L2_ENC_HW_PRESET_FAST);
  143. INIT_ERROR(ret < 0, "Failed to setHWPresetType");
  144. ret = encoder_->setRateControlMode(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
  145. INIT_ERROR(ret < 0, "Failed to setRateControlMode");
  146. /* ここに来たということはエンコーダは初期化されている
  147. 初期化されているということは設定するべきは調整されたレートではなく
  148. 最初の目標値であるべき BitrateAdjuster も初期化する*/
  149. bitrate_adjuster_.reset(new webrtc::BitrateAdjuster(.5, .95));
  150. bitrate_adjuster_->SetTargetBitrateBps(target_bitrate_bps_);
  151. SetBitrateBps(target_bitrate_bps_);
  152. ret = encoder_->setIDRInterval(key_frame_interval_);
  153. INIT_ERROR(ret < 0, "Failed to setIDRInterval");
  154. ret = encoder_->setIFrameInterval(0);
  155. INIT_ERROR(ret < 0, "Failed to setIFrameInterval");
  156. ret = encoder_->setFrameRate(framerate_, 1);
  157. INIT_ERROR(ret < 0, "Failed to setFrameRate");
  158. if (use_native_) {
  159. if (use_dmabuff_ || use_converter) {
  160. ret = encoder_->output_plane.reqbufs(V4L2_MEMORY_DMABUF, 10);
  161. INIT_ERROR(ret < 0, "Failed to reqbufs at encoder output_plane");
  162. int fd;
  163. NvBufSurf::NvCommonAllocateParams cParams;
  164. cParams.width = width_;
  165. cParams.height = height_;
  166. cParams.layout = NVBUF_LAYOUT_PITCH;
  167. cParams.colorFormat = NVBUF_COLOR_FORMAT_YUV420;
  168. cParams.memtag = NvBufSurfaceTag_VIDEO_ENC;
  169. cParams.memType = NVBUF_MEM_SURFACE_ARRAY;
  170. for (uint32_t i = 0; i < encoder_->output_plane.getNumBuffers(); i++) {
  171. ret = NvBufSurf::NvAllocate(&cParams, 1, &fd);
  172. INIT_ERROR(ret, "Failed to create NvBuffer");
  173. RTC_LOG(LS_ERROR) << "NvBufferCreateEx i:" << i << " fd:" << fd;
  174. output_plane_fd_[i] = fd;
  175. }
  176. } else {
  177. ret = encoder_->output_plane.setupPlane(V4L2_MEMORY_USERPTR, 1, false,
  178. false);
  179. INIT_ERROR(ret < 0, "Failed to setupPlane at encoder output_plane");
  180. }
  181. } else {
  182. ret = encoder_->output_plane.setupPlane(V4L2_MEMORY_MMAP, 1, true, false);
  183. INIT_ERROR(ret < 0, "Failed to setupPlane at encoder output_plane");
  184. }
  185. ret = encoder_->capture_plane.setupPlane(V4L2_MEMORY_MMAP, 1, true, false);
  186. INIT_ERROR(ret < 0, "Failed to setupPlane at capture_plane");
  187. ret = encoder_->subscribeEvent(V4L2_EVENT_EOS, 0, 0);
  188. INIT_ERROR(ret < 0, "Failed to subscribeEvent V4L2_EVENT_EOS");
  189. ret = encoder_->output_plane.setStreamStatus(true);
  190. INIT_ERROR(ret < 0, "Failed to setStreamStatus at encoder output_plane");
  191. ret = encoder_->capture_plane.setStreamStatus(true);
  192. INIT_ERROR(ret < 0, "Failed to setStreamStatus at encoder capture_plane");
  193. encoder_->capture_plane.setDQThreadCallback(EncodeFinishedCallbackFunction);
  194. encoder_->capture_plane.startDQThread(this);
  195. for (uint32_t i = 0; i < encoder_->capture_plane.getNumBuffers(); i++) {
  196. struct v4l2_buffer v4l2_buf;
  197. struct v4l2_plane planes[MAX_PLANES];
  198. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  199. memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
  200. v4l2_buf.index = i;
  201. v4l2_buf.m.planes = planes;
  202. ret = encoder_->capture_plane.qBuffer(v4l2_buf, NULL);
  203. INIT_ERROR(ret < 0, "Failed to qBuffer at encoder capture_plane");
  204. }
  205. configured_framerate_ = framerate_;
  206. return WEBRTC_VIDEO_CODEC_OK;
  207. }
  208. void JetsonVideoEncoder::JetsonRelease() {
  209. if (!encoder_)
  210. return;
  211. SendEOS();
  212. encoder_->capture_plane.waitForDQThread(2000);
  213. encoder_->capture_plane.deinitPlane();
  214. if (use_dmabuff_) {
  215. for (uint32_t i = 0; i < encoder_->output_plane.getNumBuffers(); i++) {
  216. if (encoder_->output_plane.unmapOutputBuffers(i, output_plane_fd_[i]) <
  217. 0) {
  218. RTC_LOG(LS_ERROR)
  219. << "Failed to unmapOutputBuffers at encoder output_plane";
  220. }
  221. if (NvBufSurf::NvDestroy(output_plane_fd_[i]) < 0) {
  222. RTC_LOG(LS_ERROR)
  223. << "Failed to NvBufferDestroy at encoder output_plane";
  224. }
  225. }
  226. } else {
  227. encoder_->output_plane.deinitPlane();
  228. }
  229. delete encoder_;
  230. encoder_ = nullptr;
  231. }
  232. void JetsonVideoEncoder::SendEOS() {
  233. if (encoder_->output_plane.getStreamStatus()) {
  234. struct v4l2_buffer v4l2_buf;
  235. struct v4l2_plane planes[MAX_PLANES];
  236. NvBuffer* buffer;
  237. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  238. memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
  239. v4l2_buf.m.planes = planes;
  240. if (encoder_->output_plane.getNumQueuedBuffers() ==
  241. encoder_->output_plane.getNumBuffers()) {
  242. if (encoder_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 10) < 0) {
  243. RTC_LOG(LS_ERROR) << "Failed to dqBuffer at encoder output_plane";
  244. }
  245. }
  246. planes[0].bytesused = 0;
  247. for (int i = 0; i < buffer->n_planes; i++) {
  248. buffer->planes[i].bytesused = 0;
  249. }
  250. if (encoder_->output_plane.qBuffer(v4l2_buf, NULL) < 0) {
  251. RTC_LOG(LS_ERROR) << "Failed to qBuffer at encoder output_plane";
  252. }
  253. }
  254. }
  255. bool JetsonVideoEncoder::EncodeFinishedCallbackFunction(
  256. struct v4l2_buffer* v4l2_buf,
  257. NvBuffer* buffer,
  258. NvBuffer* shared_buffer,
  259. void* data) {
  260. return ((JetsonVideoEncoder*)data)
  261. ->EncodeFinishedCallback(v4l2_buf, buffer, shared_buffer);
  262. }
  263. bool JetsonVideoEncoder::EncodeFinishedCallback(struct v4l2_buffer* v4l2_buf,
  264. NvBuffer* buffer,
  265. NvBuffer* shared_buffer) {
  266. if (!v4l2_buf) {
  267. RTC_LOG(LS_INFO) << __FUNCTION__ << " v4l2_buf is null";
  268. return false;
  269. }
  270. if (buffer->planes[0].bytesused == 0) {
  271. RTC_LOG(LS_INFO) << __FUNCTION__ << " buffer size is zero";
  272. return false;
  273. }
  274. uint64_t timestamp = v4l2_buf->timestamp.tv_sec * rtc::kNumMicrosecsPerSec +
  275. v4l2_buf->timestamp.tv_usec;
  276. std::unique_ptr<FrameParams> params;
  277. {
  278. webrtc::MutexLock lock(&frame_params_lock_);
  279. do {
  280. if (frame_params_.empty()) {
  281. RTC_LOG(LS_WARNING)
  282. << __FUNCTION__
  283. << "Frame parameter is not found. SkipFrame timestamp:"
  284. << timestamp;
  285. return true;
  286. }
  287. params = std::move(frame_params_.front());
  288. frame_params_.pop();
  289. } while (params->timestamp_us < timestamp);
  290. if (params->timestamp_us != timestamp) {
  291. RTC_LOG(LS_WARNING)
  292. << __FUNCTION__
  293. << "Frame parameter is not found. SkipFrame timestamp:" << timestamp;
  294. return true;
  295. }
  296. }
  297. v4l2_ctrl_videoenc_outputbuf_metadata enc_metadata;
  298. if (encoder_->getMetadata(v4l2_buf->index, enc_metadata) != 0) {
  299. RTC_LOG(LS_WARNING) << __FUNCTION__
  300. << "getMetadata failed. SkipFrame timestamp:"
  301. << timestamp;
  302. return true;
  303. }
  304. SendFrame(buffer->planes[0].data, buffer->planes[0].bytesused,
  305. std::move(params), &enc_metadata);
  306. if (encoder_->capture_plane.qBuffer(*v4l2_buf, NULL) < 0) {
  307. RTC_LOG(LS_ERROR) << __FUNCTION__ << "Failed to qBuffer at capture_plane";
  308. return false;
  309. }
  310. return true;
  311. }
  312. int32_t JetsonVideoEncoder::RegisterEncodeCompleteCallback(
  313. webrtc::EncodedImageCallback* callback) {
  314. callback_ = callback;
  315. return WEBRTC_VIDEO_CODEC_OK;
  316. }
  317. void JetsonVideoEncoder::SetRates(const RateControlParameters& parameters) {
  318. if (encoder_ == nullptr)
  319. return;
  320. if (parameters.bitrate.get_sum_bps() <= 0 || parameters.framerate_fps <= 0)
  321. return;
  322. RTC_LOG(LS_INFO) << __FUNCTION__ << " framerate:" << parameters.framerate_fps
  323. << " bitrate:" << parameters.bitrate.ToString();
  324. if (svc_controller_) {
  325. svc_controller_->OnRatesUpdated(parameters.bitrate);
  326. }
  327. framerate_ = parameters.framerate_fps;
  328. target_bitrate_bps_ = parameters.bitrate.get_sum_bps();
  329. bitrate_adjuster_->SetTargetBitrateBps(target_bitrate_bps_);
  330. return;
  331. }
  332. void JetsonVideoEncoder::SetFramerate(uint32_t framerate) {
  333. if (configured_framerate_ == framerate) {
  334. return;
  335. }
  336. RTC_LOG(LS_INFO) << __FUNCTION__ << " " << framerate << "fps";
  337. if (encoder_->setFrameRate(framerate, 1) < 0) {
  338. RTC_LOG(LS_ERROR) << "Failed to set bitrate";
  339. return;
  340. }
  341. configured_framerate_ = framerate;
  342. }
  343. void JetsonVideoEncoder::SetBitrateBps(uint32_t bitrate_bps) {
  344. if (bitrate_bps < 300000 || (configured_bitrate_bps_ == bitrate_bps &&
  345. configured_framerate_ == framerate_)) {
  346. return;
  347. }
  348. configured_bitrate_bps_ = bitrate_bps;
  349. // VP9 の setBitrate は、設定されたフレームレートを見ずに
  350. // 60fps での bps を見てるっぽいので、ここで渡す bps を調整する
  351. if (codec_.codecType == webrtc::kVideoCodecVP9) {
  352. auto adjusted_bps = bitrate_bps * 60 / configured_framerate_;
  353. RTC_LOG(LS_INFO) << __FUNCTION__ << " bps=" << bitrate_bps
  354. << " adjusted_bps=" << adjusted_bps;
  355. bitrate_bps = adjusted_bps;
  356. } else {
  357. RTC_LOG(LS_INFO) << __FUNCTION__ << " bps=" << bitrate_bps;
  358. }
  359. if (encoder_->setBitrate(bitrate_bps) < 0) {
  360. RTC_LOG(LS_ERROR) << "Failed to setBitrate";
  361. return;
  362. }
  363. }
  364. webrtc::VideoEncoder::EncoderInfo JetsonVideoEncoder::GetEncoderInfo() const {
  365. EncoderInfo info;
  366. info.supports_native_handle = true;
  367. info.implementation_name = "Jetson Video Encoder";
  368. // if (codec_.codecType == webrtc::kVideoCodecH264) {
  369. static const int kLowH264QpThreshold = 34;
  370. static const int kHighH264QpThreshold = 40;
  371. info.scaling_settings = VideoEncoder::ScalingSettings(kLowH264QpThreshold,
  372. kHighH264QpThreshold);
  373. // } else if (codec_.codecType == webrtc::kVideoCodecH265) {
  374. // static const int kLowH265QpThreshold = 34;
  375. // static const int kHighH265QpThreshold = 40;
  376. // info.scaling_settings = VideoEncoder::ScalingSettings(kLowH265QpThreshold,
  377. // kHighH265QpThreshold);
  378. // } else if (codec_.codecType == webrtc::kVideoCodecVP8) {
  379. // static const int kLowVp8QpThreshold = 29;
  380. // static const int kHighVp8QpThreshold = 95;
  381. // info.scaling_settings =
  382. // VideoEncoder::ScalingSettings(kLowVp8QpThreshold, kHighVp8QpThreshold);
  383. // } else if (codec_.codecType == webrtc::kVideoCodecVP9) {
  384. // static const int kLowVp9QpThreshold = 150;
  385. // static const int kHighVp9QpThreshold = 151;
  386. // info.scaling_settings =
  387. // VideoEncoder::ScalingSettings(kLowVp9QpThreshold, kHighVp9QpThreshold);
  388. // } else if (codec_.codecType == webrtc::kVideoCodecAV1) {
  389. // static const int kLowAv1QpThreshold = 145;
  390. // static const int kHighAv1QpThreshold = 205;
  391. // info.scaling_settings =
  392. // VideoEncoder::ScalingSettings(kLowAv1QpThreshold, kHighAv1QpThreshold);
  393. // }
  394. return info;
  395. }
  396. int32_t JetsonVideoEncoder::Encode(
  397. const webrtc::VideoFrame& input_frame,
  398. const std::vector<webrtc::VideoFrameType>* frame_types) {
  399. if (!callback_) {
  400. RTC_LOG(LS_WARNING)
  401. << "InitEncode() has been called, but a callback function "
  402. << "has not been set with RegisterEncodeCompleteCallback()";
  403. return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  404. }
  405. int fd = 0;
  406. webrtc::VideoType video_type;
  407. uint8_t* native_data;
  408. rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer =
  409. input_frame.video_frame_buffer();
  410. std::shared_ptr<JetsonJpegDecoder> decoder;
  411. // if (frame_buffer->type() == webrtc::VideoFrameBuffer::Type::kNative) {
  412. // use_native_ = true;
  413. // JetsonBuffer* jetson_buffer =
  414. // static_cast<JetsonBuffer*>(frame_buffer.get());
  415. // video_type = jetson_buffer->VideoType();
  416. // raw_width_ = jetson_buffer->RawWidth();
  417. // raw_height_ = jetson_buffer->RawHeight();
  418. // use_dmabuff_ = true;
  419. // fd = jetson_buffer->DecodedFd();
  420. // decode_pixfmt_ = jetson_buffer->V4L2PixelFormat();
  421. // decoder = jetson_buffer->JpegDecoder();
  422. // } else {
  423. use_native_ = false;
  424. // }
  425. if (encoder_ == nullptr) {
  426. if (JetsonConfigure() != WEBRTC_VIDEO_CODEC_OK) {
  427. RTC_LOG(LS_ERROR) << "Failed to JetsonConfigure";
  428. return WEBRTC_VIDEO_CODEC_ERROR;
  429. }
  430. }
  431. bool force_key_frame = false;
  432. if (frame_types != nullptr) {
  433. RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1));
  434. if ((*frame_types)[0] == webrtc::VideoFrameType::kEmptyFrame) {
  435. return WEBRTC_VIDEO_CODEC_OK;
  436. }
  437. if ((*frame_types)[0] == webrtc::VideoFrameType::kVideoFrameKey) {
  438. if (encoder_->forceIDR() < 0) {
  439. RTC_LOG(LS_ERROR) << "Failed to forceIDR";
  440. }
  441. }
  442. }
  443. SetFramerate(framerate_);
  444. SetBitrateBps(bitrate_adjuster_->GetAdjustedBitrateBps());
  445. {
  446. webrtc::MutexLock lock(&frame_params_lock_);
  447. frame_params_.push(absl::make_unique<FrameParams>(
  448. frame_buffer->width(), frame_buffer->height(),
  449. input_frame.render_time_ms(), input_frame.ntp_time_ms(),
  450. input_frame.timestamp_us(), input_frame.timestamp(),
  451. input_frame.rotation(), input_frame.color_space(), decoder));
  452. }
  453. struct v4l2_buffer v4l2_buf;
  454. struct v4l2_plane planes[MAX_PLANES];
  455. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  456. memset(planes, 0, sizeof(planes));
  457. v4l2_buf.m.planes = planes;
  458. if (use_native_) {
  459. NvBuffer* buffer;
  460. if (encoder_->output_plane.getNumQueuedBuffers() ==
  461. encoder_->output_plane.getNumBuffers()) {
  462. if (encoder_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 10) < 0) {
  463. RTC_LOG(LS_ERROR) << "Failed to dqBuffer at encoder output_plane";
  464. return WEBRTC_VIDEO_CODEC_ERROR;
  465. }
  466. } else {
  467. buffer = encoder_->output_plane.getNthBuffer(
  468. encoder_->output_plane.getNumQueuedBuffers());
  469. v4l2_buf.index = encoder_->output_plane.getNumQueuedBuffers();
  470. }
  471. int src_dma_fd = -1;
  472. if (use_dmabuff_) {
  473. src_dma_fd = fd;
  474. } else if (video_type == webrtc::VideoType::kYUY2 ||
  475. video_type == webrtc::VideoType::kUYVY) {
  476. buffer->planes[0].bytesused = buffer->planes[0].fmt.width *
  477. buffer->planes[0].fmt.bytesperpixel *
  478. buffer->planes[0].fmt.height;
  479. buffer->planes[0].data = native_data;
  480. } else if (video_type == webrtc::VideoType::kI420) {
  481. size_t offset = 0;
  482. for (int i = 0; i < buffer->n_planes; i++) {
  483. buffer->planes[i].bytesused = buffer->planes[i].fmt.width *
  484. buffer->planes[i].fmt.bytesperpixel *
  485. buffer->planes[i].fmt.height;
  486. buffer->planes[i].data = native_data + offset;
  487. offset += buffer->planes[i].bytesused;
  488. }
  489. } else if (video_type == webrtc::VideoType::kYV12) {
  490. size_t offset = 0;
  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. offset += buffer->planes[0].bytesused;
  496. buffer->planes[2].bytesused = buffer->planes[1].fmt.width *
  497. buffer->planes[1].fmt.bytesperpixel *
  498. buffer->planes[1].fmt.height;
  499. buffer->planes[2].data = native_data + offset;
  500. offset += buffer->planes[2].bytesused;
  501. buffer->planes[1].bytesused = buffer->planes[2].fmt.width *
  502. buffer->planes[2].fmt.bytesperpixel *
  503. buffer->planes[2].fmt.height;
  504. buffer->planes[1].data = native_data + offset;
  505. } else {
  506. RTC_LOG(LS_ERROR) << "Unsupported webrtc::VideoType";
  507. return WEBRTC_VIDEO_CODEC_ERROR;
  508. }
  509. NvBufSurf::NvCommonTransformParams transform_params;
  510. /* Indicates which of the transform parameters are valid */
  511. memset(&transform_params, 0, sizeof(transform_params));
  512. transform_params.src_top = 0;
  513. transform_params.src_left = 0;
  514. transform_params.src_width = raw_width_;
  515. transform_params.src_height = raw_height_;
  516. transform_params.dst_top = 0;
  517. transform_params.dst_left = 0;
  518. transform_params.dst_width = width_;
  519. transform_params.dst_height = height_;
  520. transform_params.flag =
  521. (NvBufSurfTransform_Transform_Flag)(NVBUFSURF_TRANSFORM_FILTER |
  522. NVBUFSURF_TRANSFORM_CROP_SRC);
  523. transform_params.flip = NvBufSurfTransform_None;
  524. transform_params.filter = NvBufSurfTransformInter_Bilinear;
  525. if (NvBufSurf::NvTransform(&transform_params, src_dma_fd,
  526. output_plane_fd_[v4l2_buf.index])) {
  527. RTC_LOG(LS_ERROR) << "Failed to NvBufferTransform";
  528. return WEBRTC_VIDEO_CODEC_ERROR;
  529. }
  530. planes[0].m.fd = output_plane_fd_[v4l2_buf.index];
  531. planes[0].bytesused = 1234;
  532. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
  533. v4l2_buf.memory = V4L2_MEMORY_DMABUF;
  534. v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  535. v4l2_buf.timestamp.tv_sec =
  536. input_frame.timestamp_us() / rtc::kNumMicrosecsPerSec;
  537. v4l2_buf.timestamp.tv_usec =
  538. input_frame.timestamp_us() % rtc::kNumMicrosecsPerSec;
  539. if (encoder_->output_plane.qBuffer(v4l2_buf, nullptr) < 0) {
  540. RTC_LOG(LS_ERROR) << "Failed to qBuffer at converter output_plane";
  541. return WEBRTC_VIDEO_CODEC_ERROR;
  542. }
  543. } else {
  544. NvBuffer* buffer;
  545. RTC_LOG(LS_VERBOSE) << __FUNCTION__ << " output_plane.getNumBuffers: "
  546. << encoder_->output_plane.getNumBuffers()
  547. << " output_plane.getNumQueuedBuffers: "
  548. << encoder_->output_plane.getNumQueuedBuffers();
  549. if (encoder_->output_plane.getNumQueuedBuffers() ==
  550. encoder_->output_plane.getNumBuffers()) {
  551. if (encoder_->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, 10) < 0) {
  552. RTC_LOG(LS_ERROR) << "Failed to dqBuffer at encoder output_plane";
  553. return WEBRTC_VIDEO_CODEC_ERROR;
  554. }
  555. } else {
  556. buffer = encoder_->output_plane.getNthBuffer(
  557. encoder_->output_plane.getNumQueuedBuffers());
  558. v4l2_buf.index = encoder_->output_plane.getNumQueuedBuffers();
  559. }
  560. rtc::scoped_refptr<const webrtc::I420BufferInterface> i420_buffer =
  561. frame_buffer->ToI420();
  562. for (uint32_t i = 0; i < buffer->n_planes; i++) {
  563. const uint8_t* source_data;
  564. int source_stride;
  565. if (i == 0) {
  566. source_data = i420_buffer->DataY();
  567. source_stride = i420_buffer->StrideY();
  568. } else if (i == 1) {
  569. source_data = i420_buffer->DataU();
  570. source_stride = i420_buffer->StrideU();
  571. } else if (i == 2) {
  572. source_data = i420_buffer->DataV();
  573. source_stride = i420_buffer->StrideV();
  574. } else {
  575. break;
  576. }
  577. NvBuffer::NvBufferPlane& plane = buffer->planes[i];
  578. std::streamsize bytes_to_read = plane.fmt.bytesperpixel * plane.fmt.width;
  579. uint8_t* input_data = plane.data;
  580. plane.bytesused = 0;
  581. for (uint32_t j = 0; j < plane.fmt.height; j++) {
  582. memcpy(input_data, source_data + (source_stride * j), bytes_to_read);
  583. input_data += plane.fmt.stride;
  584. }
  585. plane.bytesused = plane.fmt.stride * plane.fmt.height;
  586. }
  587. v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  588. v4l2_buf.timestamp.tv_sec =
  589. input_frame.timestamp_us() / rtc::kNumMicrosecsPerSec;
  590. v4l2_buf.timestamp.tv_usec =
  591. input_frame.timestamp_us() % rtc::kNumMicrosecsPerSec;
  592. for (int i = 0; i < MAX_PLANES; i++) {
  593. NvBufSurface* surf = 0;
  594. if (NvBufSurfaceFromFd(buffer->planes[i].fd, (void**)(&surf)) == -1) {
  595. RTC_LOG(LS_ERROR) << __FUNCTION__ << "Failed to NvBufSurfaceFromFd";
  596. return WEBRTC_VIDEO_CODEC_ERROR;
  597. }
  598. if (NvBufSurfaceSyncForDevice(surf, 0, i) == -1) {
  599. RTC_LOG(LS_ERROR) << "Failed to NvBufSurfaceSyncForDevice";
  600. return WEBRTC_VIDEO_CODEC_ERROR;
  601. }
  602. }
  603. if (encoder_->output_plane.qBuffer(v4l2_buf, nullptr) < 0) {
  604. RTC_LOG(LS_ERROR) << "Failed to qBuffer at encoder output_plane";
  605. return WEBRTC_VIDEO_CODEC_ERROR;
  606. }
  607. }
  608. return WEBRTC_VIDEO_CODEC_OK;
  609. }
  610. int32_t JetsonVideoEncoder::SendFrame(
  611. unsigned char* buffer,
  612. size_t size,
  613. std::unique_ptr<FrameParams> params,
  614. v4l2_ctrl_videoenc_outputbuf_metadata* enc_metadata) {
  615. if (!callback_) {
  616. RTC_LOG(LS_WARNING)
  617. << "InitEncode() has been called, but a callback function "
  618. << "has not been set with RegisterEncodeCompleteCallback()";
  619. return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  620. }
  621. // encoded_image_.SetRtpTimestamp(params->timestamp_rtp);
  622. encoded_image_.SetTimestamp(params->timestamp_rtp);
  623. encoded_image_.SetColorSpace(params->color_space);
  624. encoded_image_._encodedWidth = params->width;
  625. encoded_image_._encodedHeight = params->height;
  626. encoded_image_.capture_time_ms_ = params->render_time_ms;
  627. encoded_image_.ntp_time_ms_ = params->ntp_time_ms;
  628. encoded_image_.rotation_ = params->rotation;
  629. encoded_image_.qp_ = enc_metadata->AvgQP;
  630. // if (enc_metadata->KeyFrame) {
  631. // encoded_image_.SetFrameType(webrtc::VideoFrameType::kVideoFrameKey);
  632. // } else {
  633. // encoded_image_.SetFrameType(webrtc::VideoFrameType::kVideoFrameDelta);
  634. // }
  635. if (enc_metadata->KeyFrame) {
  636. encoded_image_._frameType= webrtc::VideoFrameType::kVideoFrameKey;
  637. } else {
  638. encoded_image_._frameType= webrtc::VideoFrameType::kVideoFrameDelta;
  639. }
  640. webrtc::CodecSpecificInfo codec_specific;
  641. codec_specific.codecType = codec_.codecType;
  642. // if (codec_.codecType == webrtc::kVideoCodecH264) {
  643. auto encoded_image_buffer =
  644. webrtc::EncodedImageBuffer::Create(buffer, size);
  645. encoded_image_.SetEncodedData(encoded_image_buffer);
  646. codec_specific.codecSpecific.H264.packetization_mode =
  647. webrtc::H264PacketizationMode::NonInterleaved;
  648. // webrtc::H264PacketizationMode::SingleNalUnit;
  649. // } else if (codec_.codecType == webrtc::kVideoCodecH265) {
  650. // auto encoded_image_buffer =
  651. // webrtc::EncodedImageBuffer::Create(buffer, size);
  652. // encoded_image_.SetEncodedData(encoded_image_buffer);
  653. // } else if (codec_.codecType == webrtc::kVideoCodecAV1 ||
  654. // codec_.codecType == webrtc::kVideoCodecVP9 ||
  655. // codec_.codecType == webrtc::kVideoCodecVP8) {
  656. // if ((buffer[0] == 'D') && (buffer[1] == 'K') && (buffer[2] == 'I') &&
  657. // (buffer[3] == 'F')) {
  658. // buffer += 32;
  659. // size -= 32;
  660. // // }
  661. // buffer += 12;
  662. // size -= 12;
  663. // rtc::scoped_refptr<webrtc::EncodedImageBuffer> encoded_image_buffer;
  664. // if (codec_.codecType == webrtc::kVideoCodecAV1) {
  665. // if (buffer[2] == 0x0a) {
  666. // int obu_size = buffer[3];
  667. // obu_seq_header_.resize(obu_size + 2);
  668. // memcpy(obu_seq_header_.data(), buffer + 2, obu_size + 2);
  669. // }
  670. // if (enc_metadata->KeyFrame && buffer[2] != 0x0a) {
  671. // std::vector<uint8_t> new_buffer;
  672. // new_buffer.resize(obu_seq_header_.size() + size);
  673. // uint8_t* p = new_buffer.data();
  674. // // OBU_TEMPORAL_DELIMITER
  675. // memcpy(p, buffer, 2);
  676. // p += 2;
  677. // // OBU_SEQUENCE_HEADER
  678. // memcpy(p, obu_seq_header_.data(), obu_seq_header_.size());
  679. // p += obu_seq_header_.size();
  680. // // OBU_FRAME
  681. // memcpy(p, buffer + 2, size - 2);
  682. // // RTC_LOG(LS_ERROR) << "\n" << hex_dump(new_buffer.data(), 64);
  683. // // save_to_file("keyframe2.obu", new_buffer.data(), new_buffer.size());
  684. // encoded_image_buffer = webrtc::EncodedImageBuffer::Create(
  685. // new_buffer.data(), new_buffer.size());
  686. // } else {
  687. // encoded_image_buffer = webrtc::EncodedImageBuffer::Create(buffer, size);
  688. // }
  689. // } else {
  690. encoded_image_buffer = webrtc::EncodedImageBuffer::Create(buffer, size);
  691. // }
  692. encoded_image_.SetEncodedData(encoded_image_buffer);
  693. // if (codec_.codecType == webrtc::kVideoCodecVP8) {
  694. // codec_specific.codecSpecific.VP8.keyIdx = webrtc::kNoKeyIdx;
  695. // // nonReference かを知ることはできなかった
  696. // codec_specific.codecSpecific.VP8.nonReference = false;
  697. // } else if (codec_.codecType == webrtc::kVideoCodecVP9) {
  698. // if (enc_metadata->KeyFrame) {
  699. // gof_idx_ = 0;
  700. // }
  701. // codec_specific.codecSpecific.VP9.inter_pic_predicted =
  702. // enc_metadata->KeyFrame ? false : true;
  703. // codec_specific.codecSpecific.VP9.flexible_mode = false;
  704. // codec_specific.codecSpecific.VP9.ss_data_available =
  705. // enc_metadata->KeyFrame ? true : false;
  706. // codec_specific.codecSpecific.VP9.temporal_idx = webrtc::kNoTemporalIdx;
  707. // codec_specific.codecSpecific.VP9.temporal_up_switch = true;
  708. // codec_specific.codecSpecific.VP9.inter_layer_predicted = false;
  709. // codec_specific.codecSpecific.VP9.gof_idx =
  710. // static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof);
  711. // codec_specific.codecSpecific.VP9.num_spatial_layers = 1;
  712. // codec_specific.codecSpecific.VP9.first_frame_in_picture = true;
  713. // codec_specific.codecSpecific.VP9.spatial_layer_resolution_present = false;
  714. // if (codec_specific.codecSpecific.VP9.ss_data_available) {
  715. // codec_specific.codecSpecific.VP9.spatial_layer_resolution_present =
  716. // true;
  717. // codec_specific.codecSpecific.VP9.width[0] =
  718. // encoded_image_._encodedWidth;
  719. // codec_specific.codecSpecific.VP9.height[0] =
  720. // encoded_image_._encodedHeight;
  721. // codec_specific.codecSpecific.VP9.gof.CopyGofInfoVP9(gof_);
  722. // }
  723. // }
  724. // else if (codec_.codecType == webrtc::kVideoCodecAV1) {
  725. // bool is_key =
  726. // encoded_image_._frameType == webrtc::VideoFrameType::kVideoFrameKey;
  727. // std::vector<webrtc::ScalableVideoController::LayerFrameConfig>
  728. // layer_frames = svc_controller_->NextFrameConfig(is_key);
  729. // codec_specific.end_of_picture = true;
  730. // codec_specific.scalability_mode = scalability_mode_;
  731. // codec_specific.generic_frame_info =
  732. // svc_controller_->OnEncodeDone(layer_frames[0]);
  733. // if (is_key && codec_specific.generic_frame_info) {
  734. // codec_specific.template_structure =
  735. // svc_controller_->DependencyStructure();
  736. // auto& resolutions = codec_specific.template_structure->resolutions;
  737. // resolutions = {webrtc::RenderResolution(encoded_image_._encodedWidth,
  738. // encoded_image_._encodedHeight)};
  739. // }
  740. // }
  741. // }
  742. RTC_LOG(LS_VERBOSE) << "key_frame=" << enc_metadata->KeyFrame
  743. << " size=" << size << " qp=" << encoded_image_.qp_;
  744. webrtc::EncodedImageCallback::Result result =
  745. callback_->OnEncodedImage(encoded_image_, &codec_specific);
  746. if (result.error != webrtc::EncodedImageCallback::Result::OK) {
  747. RTC_LOG(LS_ERROR) << __FUNCTION__
  748. << " OnEncodedImage failed error:" << result.error;
  749. return WEBRTC_VIDEO_CODEC_ERROR;
  750. }
  751. bitrate_adjuster_->Update(size);
  752. return WEBRTC_VIDEO_CODEC_OK;
  753. }
  754. } // namespace sora