Skip to content

Commit e33d457

Browse files
authored
Merge pull request #6 from dji-sdk/release/v1.1.1
* Added support for subscribing to the 1080p high-bitrate stream on D…
2 parents 3ca0445 + 76e3365 commit e33d457

15 files changed

+316
-71
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ file(GLOB_RECURSE MODULE_SAMPLE_SRC
2020
examples/init/key_store_default.cc)
2121

2222
include_directories(include)
23+
include_directories(examples)
2324
include_directories(examples/common)
2425

2526
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_HOST_SYSTEM_PROCESSOR})
@@ -90,7 +91,9 @@ if (OpenCV_FOUND AND FFMPEG_FOUND)
9091
target_link_libraries(sample_liveview ${SAMPLE_LIB})
9192

9293
add_executable(test_liveview examples/liveview/test_liveview_main.cc)
94+
add_executable(test_liveview_dual examples/liveview/test_liveview_dual_main.cc)
9395
target_link_libraries(test_liveview ${SAMPLE_LIB})
96+
target_link_libraries(test_liveview_dual ${SAMPLE_LIB})
9497

9598
add_executable(pressure_test examples/test/pressure_test.cc)
9699
target_link_libraries(pressure_test ${SAMPLE_LIB})

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# DJI Edge SDK (ESDK)
22

3-
![](https://img.shields.io/badge/version-V1.1.0-yellow.svg)
3+
![](https://img.shields.io/badge/version-V1.1.1-yellow.svg)
44
![](https://img.shields.io/badge/platform-linux-green.svg)
55
![](https://img.shields.io/badge/license-MIT-blue.svg)
66

@@ -28,7 +28,7 @@ Edge computing offers a secure local communication link, ensuring communication
2828
Edge computing can process and transmit data in unstable network environments, utilizing small data channels to enhance transmission efficiency. This ensures aircraft achieve efficient data processing and transmission across various environments.
2929

3030
## Dependencies
31-
* libssh2 (version 1.10.x or higher)
31+
* libssh2 (reference version 1.10.0)
3232
* openssl (reference version 1.1.1f)
3333
* opencv (version 3.4.16 or higher)
3434
* ffmpeg (version 4.13 or higher)

examples/common/image_processor.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ ImageProcessor::~ImageProcessor() {}
4646
std::shared_ptr<ImageProcessor> CreateImageProcessor(
4747
const ImageProcessor::Options& option) {
4848
if (option.name == std::string("display")) {
49-
return std::make_shared<ImageDisplayProcessor>(option.alias);
49+
return std::make_shared<ImageDisplayProcessor>(option.alias, option.userdata);
5050
}
5151
if (option.name == std::string("yolovfastest")) {
5252
return std::make_shared<ImageProcessorYolovFastest>(option.alias);

examples/common/image_processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ImageProcessor {
3737
struct Options {
3838
std::string name;
3939
std::string alias;
40+
std::shared_ptr<void> userdata;
4041
};
4142

4243
virtual int32_t Init() { return 0; }

examples/common/image_processor_display.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,21 @@
2222
#ifndef __IMAGE_PROCESSOR_DIAPLAY_H__
2323
#define __IMAGE_PROCESSOR_DIAPLAY_H__
2424

25+
#include <memory>
2526
#include "opencv2/opencv.hpp"
27+
#include "liveview/sample_liveview.h"
2628

2729
namespace edge_app {
2830

2931
class ImageDisplayProcessor : public ImageProcessor {
3032
public:
31-
ImageDisplayProcessor(const std::string& name) : name_(name) {
33+
ImageDisplayProcessor(const std::string& name, std::shared_ptr<void> userdata) : name_(name) {
3234
cv::namedWindow(name.c_str(), cv::WINDOW_NORMAL);
3335
cv::resizeWindow(name.c_str(), 960, 540);
3436
cv::moveWindow(name.c_str(), rand() & 0xFF, rand() & 0xFF);
37+
if (userdata) {
38+
liveview_sample_ = std::static_pointer_cast<LiveviewSample>(userdata);
39+
}
3540
}
3641

3742
~ImageDisplayProcessor() override {}
@@ -40,14 +45,19 @@ class ImageDisplayProcessor : public ImageProcessor {
4045
std::string h = std::to_string(image->size().width);
4146
std::string w = std::to_string(image->size().height);
4247
std::string osd = h + "x" + w;
48+
if (liveview_sample_) {
49+
auto kbps = liveview_sample_->GetStreamBitrate();
50+
osd += std::string(",") + std::to_string(kbps) + std::string("kbps");
51+
}
4352
putText(*image, osd, cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 1,
44-
cv::Scalar(0, 255, 0));
53+
cv::Scalar(0, 0, 255), 3);
4554
imshow(name_.c_str(), *image);
4655
cv::waitKey(1);
4756
}
4857

4958
private:
5059
std::string name_;
60+
std::shared_ptr<LiveviewSample> liveview_sample_;
5161
};
5262

5363
} // namespace edge_app

examples/liveview/image_processor_thread.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ void ImageProcessorThread::InputImage(const std::shared_ptr<Image> image) {
6060
image_queue_.push(image);
6161
if (image_queue_.size() > kImageQueueSizeLimit) {
6262
image_queue_.pop();
63-
DEBUG("image queue full...");
6463
}
6564
image_queue_cv_.notify_one();
6665
}

examples/liveview/sample_liveview.cc

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525

2626
#include "liveview/liveview.h"
2727

28+
#define BITRATE_CALCULATE_BITS_PER_BYTE 8
29+
#define BITRATE_CALCULATE_INTERVAL_TIME_MS 2000
30+
2831
using namespace edge_sdk;
2932

3033
namespace edge_app {
@@ -35,9 +38,20 @@ LiveviewSample::LiveviewSample(const std::string& name) {
3538
}
3639

3740
ErrorCode LiveviewSample::StreamCallback(const uint8_t* data, size_t len) {
41+
auto now = std::chrono::system_clock::now();
3842
if (stream_processor_thread_) {
3943
stream_processor_thread_->InputStream(data, len);
4044
}
45+
46+
// for bitrate calculate
47+
receive_stream_data_total_size_ += len;
48+
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - receive_stream_data_time_).count();
49+
if (duration >= BITRATE_CALCULATE_INTERVAL_TIME_MS) {
50+
auto kbps = receive_stream_data_total_size_ * BITRATE_CALCULATE_BITS_PER_BYTE / (BITRATE_CALCULATE_INTERVAL_TIME_MS / 1000) / 1024;
51+
stream_bitrate_kbps_ = kbps;
52+
receive_stream_data_total_size_ = 0;
53+
receive_stream_data_time_ = now;
54+
}
4155
return kOk;
4256
}
4357

@@ -82,26 +96,26 @@ void LiveviewSample::LiveviewStatusCallback(
8296
DEBUG("status: %d", status);
8397
}
8498

85-
std::shared_ptr<LiveviewSample> LiveviewSample::CreateLiveview(
86-
const std::string& name, edge_sdk::Liveview::CameraType type,
99+
int32_t InitLiveviewSample(std::shared_ptr<LiveviewSample>& liveview_sample, edge_sdk::Liveview::CameraType type,
87100
edge_sdk::Liveview::StreamQuality quality,
88101
std::shared_ptr<StreamDecoder> stream_decoder,
89-
std::shared_ptr<ImageProcessor> image_processor) {
90-
auto image_processor_thread = std::make_shared<ImageProcessorThread>(name);
102+
std::shared_ptr<ImageProcessor> image_processor)
103+
{
104+
auto image_processor_thread = std::make_shared<ImageProcessorThread>(stream_decoder->Name());
91105
image_processor_thread->SetImageProcessor(image_processor);
92106

93107
auto stream_processor_thread =
94-
std::make_shared<StreamProcessorThread>(name);
108+
std::make_shared<StreamProcessorThread>(stream_decoder->Name());
95109
stream_processor_thread->SetStreamDecoder(stream_decoder);
96110
stream_processor_thread->SetImageProcessorThread(image_processor_thread);
97111

98-
auto liveview = std::make_shared<LiveviewSample>(name);
99-
auto rc = liveview->Init(type, quality, stream_processor_thread);
112+
auto rc = liveview_sample->Init(type, quality, stream_processor_thread);
100113
if (rc != kOk) {
101114
ERROR("liveview sample init failed");
115+
return -1;
102116
}
103117

104-
return liveview;
118+
return 0;
105119
}
106120

107121
ErrorCode LiveviewSample::SetCameraSource(

examples/liveview/sample_liveview.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#ifndef __SAMPLE_LIVEVIEW_H__
2323
#define __SAMPLE_LIVEVIEW_H__
2424

25+
#include <chrono>
26+
#include <atomic>
2527
#include "error_code.h"
2628
#include "image_processor.h"
2729
#include "image_processor_thread.h"
@@ -34,13 +36,7 @@ namespace edge_app {
3436

3537
class LiveviewSample {
3638
public:
37-
static std::shared_ptr<LiveviewSample> CreateLiveview(
38-
const std::string& name, edge_sdk::Liveview::CameraType type,
39-
edge_sdk::Liveview::StreamQuality quality,
40-
std::shared_ptr<StreamDecoder> stream_decoder,
41-
std::shared_ptr<ImageProcessor> image_processor);
42-
43-
LiveviewSample(const std::string& name);
39+
explicit LiveviewSample(const std::string& name);
4440
~LiveviewSample() {}
4541

4642
edge_sdk::ErrorCode Init(edge_sdk::Liveview::CameraType type,
@@ -52,6 +48,10 @@ class LiveviewSample {
5248
edge_sdk::ErrorCode SetCameraSource(
5349
edge_sdk::Liveview::CameraSource source);
5450

51+
uint32_t GetStreamBitrate() const {
52+
return stream_bitrate_kbps_.load();
53+
}
54+
5555
private:
5656
edge_sdk::ErrorCode StreamCallback(const uint8_t* data, size_t len);
5757

@@ -61,8 +61,16 @@ class LiveviewSample {
6161
std::shared_ptr<edge_sdk::Liveview> liveview_;
6262
std::shared_ptr<StreamProcessorThread> stream_processor_thread_;
6363
edge_sdk::Liveview::LiveviewStatus liveview_status_;
64+
std::atomic<uint32_t> stream_bitrate_kbps_;
65+
std::chrono::system_clock::time_point receive_stream_data_time_ = std::chrono::system_clock::now();
66+
uint32_t receive_stream_data_total_size_;
6467
};
6568

69+
int32_t InitLiveviewSample(std::shared_ptr<LiveviewSample>& liveview_sample, edge_sdk::Liveview::CameraType type,
70+
edge_sdk::Liveview::StreamQuality quality,
71+
std::shared_ptr<StreamDecoder> stream_decoder,
72+
std::shared_ptr<ImageProcessor> image_processor);
73+
6674
} // namespace edge_app
6775

6876
#endif

examples/liveview/sample_liveview_main.cc

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,10 @@ int main(int argc, char** argv) {
3838
return -1;
3939
}
4040

41-
StreamDecoder::Options decoder_option = {.name = std::string("ffmpeg")};
42-
// create fpv stream decoder
43-
auto fpv_decoder = CreateStreamDecoder(decoder_option);
44-
45-
// create fpv image processor
46-
ImageProcessor::Options fpv_image_processor_option = {
47-
.name = std::string("display"), .alias = std::string("FPVCamera")};
48-
auto fpv_image_processor = CreateImageProcessor(fpv_image_processor_option);
49-
50-
// create fpv liveview
51-
auto fpv_liveview = edge_app::LiveviewSample::CreateLiveview(
52-
"Fpv", Liveview::kCameraTypeFpv, Liveview::kStreamQuality720p,
53-
fpv_decoder, fpv_image_processor);
54-
55-
// start fpv liveview
56-
fpv_liveview->Start();
41+
// create payload liveview
42+
auto payload_liveview = std::make_shared<LiveviewSample>("Payload");
5743

44+
StreamDecoder::Options decoder_option = {.name = std::string("ffmpeg")};
5845
// create payload decoder
5946
auto payload_decoder = CreateStreamDecoder(decoder_option);
6047

@@ -64,13 +51,34 @@ int main(int argc, char** argv) {
6451
.alias = std::string("PlayloadCamera: Yolovfastest")};
6552
auto payload_image_processor = CreateImageProcessor(image_processor_option);
6653

67-
// create payload liveview
68-
auto payload_liveview = LiveviewSample::CreateLiveview(
69-
"Payload", Liveview::kCameraTypePayload, Liveview::kStreamQuality720p,
70-
payload_decoder, payload_image_processor);
54+
if (0 != InitLiveviewSample(
55+
payload_liveview, Liveview::kCameraTypePayload, Liveview::kStreamQuality1080pHigh,
56+
payload_decoder, payload_image_processor)) {
57+
ERROR("Init fpv liveview sample failed");
58+
} else {
59+
// start payload liveview
60+
payload_liveview->Start();
61+
}
62+
63+
// create fpv liveview
64+
auto fpv_liveview = std::make_shared<LiveviewSample>("Fpv");
65+
66+
// create fpv stream decoder
67+
auto fpv_decoder = CreateStreamDecoder(decoder_option);
68+
69+
// create fpv image processor
70+
ImageProcessor::Options fpv_image_processor_option = {
71+
.name = std::string("display"), .alias = std::string("FPVCamera"), .userdata = fpv_liveview};
72+
auto fpv_image_processor = CreateImageProcessor(fpv_image_processor_option);
7173

72-
// start payload liveview
73-
payload_liveview->Start();
74+
if (0 != InitLiveviewSample(
75+
fpv_liveview, Liveview::kCameraTypeFpv, Liveview::kStreamQuality720p,
76+
fpv_decoder, fpv_image_processor)) {
77+
ERROR("Init fpv liveview sample failed");
78+
} else {
79+
// start fpv liveview
80+
fpv_liveview->Start();
81+
}
7482

7583
while (1) sleep(3);
7684

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
********************************************************************
3+
*
4+
* @copyright (c) 2023 DJI. All rights reserved.
5+
*
6+
* All information contained herein is, and remains, the property of DJI.
7+
* The intellectual and technical concepts contained herein are proprietary
8+
* to DJI and may be covered by U.S. and foreign patents, patents in process,
9+
* and protected by trade secret or copyright law. Dissemination of this
10+
* information, including but not limited to data and other proprietary
11+
* material(s) incorporated within the information, in any form, is strictly
12+
* prohibited without the express written consent of DJI.
13+
*
14+
* If you receive this source code without DJI’s authorization, you may not
15+
* further disseminate the information, and you must immediately remove the
16+
* source code and notify DJI of its removal. DJI reserves the right to pursue
17+
* legal actions against you for any loss(es) or damage(s) caused by your
18+
* failure to do so.
19+
*
20+
*********************************************************************
21+
*/
22+
#include <unistd.h>
23+
24+
#include "logger.h"
25+
#include "sample_liveview.h"
26+
27+
using namespace edge_sdk;
28+
using namespace edge_app;
29+
30+
ErrorCode ESDKInit();
31+
32+
int main(int argc, char **argv) {
33+
auto rc = ESDKInit();
34+
if (rc != kOk) {
35+
ERROR("pre init failed");
36+
return -1;
37+
}
38+
39+
auto payload_quality = atoi(argv[1]);
40+
auto fpv_quality = atoi(argv[2]);
41+
42+
while (argc < 3 || payload_quality > 5 || fpv_quality > 5) {
43+
ERROR(
44+
"Usage: %s [PAYLOAD_QUOLITY] [FPV_QUALITY] [SOURCE] \nDESCRIPTION:\n "
45+
"QUALITY: 1-540p. 2-720p. 3-720pHigh. "
46+
"4-1080p. 5-1080pHigh"
47+
"\n SOURCE: 1-wide 2-zoom 3-IR \n eg: \n %s 1 3 1",
48+
argv[0], argv[0]);
49+
sleep(1);
50+
}
51+
52+
// create payload liveview sample
53+
auto payload_liveview_sample = std::make_shared<LiveviewSample>(std::string("PayloadCamera"));
54+
55+
StreamDecoder::Options decoder_option = {.name = std::string("ffmpeg")};
56+
auto payload_stream_decoder = CreateStreamDecoder(decoder_option);
57+
58+
ImageProcessor::Options payload_image_processor_option = {.name = std::string("display"),
59+
.alias = "PayloadCamera", .userdata = payload_liveview_sample};
60+
61+
auto payload_image_processor = CreateImageProcessor(payload_image_processor_option);
62+
63+
if (0 != InitLiveviewSample(
64+
payload_liveview_sample, Liveview::kCameraTypePayload, (Liveview::StreamQuality)payload_quality,
65+
payload_stream_decoder, payload_image_processor)) {
66+
ERROR("Init liveview sample failed");
67+
} else {
68+
payload_liveview_sample->Start();
69+
}
70+
71+
// create fpv liveview sample
72+
auto fpv_liveview_sample = std::make_shared<LiveviewSample>(std::string("FPV"));
73+
74+
auto fpv_stream_decoder = CreateStreamDecoder(decoder_option);
75+
76+
ImageProcessor::Options fpv_image_processor_option = {.name = std::string("display"),
77+
.alias = "FPVCamera", .userdata = fpv_liveview_sample};
78+
79+
auto fpv_image_processor = CreateImageProcessor(fpv_image_processor_option);
80+
81+
if (0 != InitLiveviewSample(
82+
fpv_liveview_sample, Liveview::kCameraTypeFpv, (Liveview::StreamQuality)fpv_quality,
83+
fpv_stream_decoder, fpv_image_processor)) {
84+
ERROR("Init liveview sample failed");
85+
} else {
86+
fpv_liveview_sample->Start();
87+
}
88+
89+
if (argc == 4) {
90+
auto src = atoi(argv[3]);
91+
INFO("set camera soure: %d", src);
92+
payload_liveview_sample->SetCameraSource((edge_sdk::Liveview::CameraSource)src);
93+
}
94+
95+
while (1) sleep(3);
96+
97+
return 0;
98+
}

0 commit comments

Comments
 (0)