Skip to content
2 changes: 1 addition & 1 deletion fpvue_config.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#define fpvue_VERSION_MAJOR 0
#define fpvue_VERSION_MINOR 13
#define fpvue_VERSION_MINOR 12
37 changes: 7 additions & 30 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ extern "C" {
#include "mavlink.h"
}

#include "minimp4.h"
#include "gstrtpreceiver.h"
#include "scheduling_helper.hpp"
#include "time_util.h"
Expand Down Expand Up @@ -75,16 +74,7 @@ pthread_cond_t video_cond;

int video_zpos = 1;

VideoCodec codec = VideoCodec::H265;
FILE *dvr_file = NULL;
MP4E_mux_t *mux ;
mp4_h26x_writer_t mp4wr;

int write_callback(int64_t offset, const void *buffer, size_t size, void *token){
FILE *f = (FILE*)token;
fseek(f, offset, SEEK_SET);
return fwrite(buffer, 1, size, f) != size;
}

void init_buffer(MppFrame frame) {
output_list->video_frm_width = mpp_frame_get_width(frame);
Expand Down Expand Up @@ -167,18 +157,10 @@ void init_buffer(MppFrame frame) {

ret = modeset_perform_modeset(drm_fd, output_list, output_list->video_request, &output_list->video_plane, mpi.frame_to_drm[0].fb_id, osd_vars.video_width, osd_vars.video_height, video_zpos);
assert(ret >= 0);
}

void *__DVR_THREAD__(void *param) {

// dvr setup
if (dvr_file != NULL){
printf("setting up dvr and mux\n");
mux = MP4E_open(0 /*sequential_mode*/, 0 /*fragmentation_mode*/, dvr_file, write_callback);
if (MP4E_STATUS_OK != mp4_h26x_write_init(&mp4wr, mux, output_list->video_frm_width, output_list->video_frm_height, codec==VideoCodec::H265))
{
printf("error: mp4_h26x_write_init failed\n");
mux = NULL;
dvr_file = NULL;
}
}
}

// __FRAME_THREAD__
Expand Down Expand Up @@ -370,12 +352,8 @@ bool feed_packet_to_decoder(MppPacket *packet,void* data_p,int data_len){
usleep(2 * 1000);
}

if (dvr_file!=NULL && mux != NULL){
int res = mp4_h26x_write_nal(&mp4wr, (const unsigned char*)data_p, data_len, -1);
// if (MP4E_STATUS_OK != res) {
// // This is expected to fail until a keyframe arrives.
// //printf("mp4_h26x_write_nal failed with %d", res);
// }
if (dvr_file!=NULL){
fwrite(data_p, data_len, 1, dvr_file);
}
return true;
}
Expand Down Expand Up @@ -500,6 +478,7 @@ int main(int argc, char **argv)
uint16_t mode_width = 0;
uint16_t mode_height = 0;
uint32_t mode_vrefresh = 0;
VideoCodec codec = VideoCodec::H265;
// Load console arguments
__BeginParseConsoleArguments__(printHelp)

Expand Down Expand Up @@ -668,8 +647,6 @@ int main(int argc, char **argv)

// Close dvr file
if (dvr_file != NULL) {
MP4E_close(mux);
mp4_h26x_write_close(&mp4wr);
fclose(dvr_file);
}

Expand Down Expand Up @@ -743,4 +720,4 @@ int main(int argc, char **argv)
close(drm_fd);

return 0;
}
}
10 changes: 9 additions & 1 deletion mavlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ void* __MAVLINK_THREAD__(void* arg) {
case MAVLINK_MSG_ID_HEARTBEAT:
// handle_heartbeat(&message);
break;

case MAVLINK_MSG_ID_RAW_IMU:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAVLINK_MSG_ID_RAW_IMU seems to be for IMU data:
https://docs.ros.org/en/melodic/api/rosflight/html/mavlink__msg__raw__imu_8h.html#a597d5ddd09d163766bb8afe327d12085
isn't there a message for temperature in mavlink ?

{
mavlink_raw_imu_t imu;
mavlink_msg_raw_imu_decode(&message, &imu);
osd_vars.telemetry_raw_imu = imu.temperature;
}
break;

case MAVLINK_MSG_ID_SYS_STATUS:
{
Expand Down Expand Up @@ -291,4 +299,4 @@ void* __MAVLINK_THREAD__(void* arg) {

printf("Mavlink thread done.\n");
return 0;
}
}
106 changes: 13 additions & 93 deletions osd.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ void modeset_paint_buffer(struct modeset_buf *buf) {
surface = cairo_image_surface_create_for_data(buf->map, CAIRO_FORMAT_ARGB32, buf->width, buf->height, buf->stride);
cr = cairo_create (surface);

cairo_select_font_face (cr, "Roboto", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, 20);
cairo_select_font_face (cr, "Roboto", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 22);

if (osd_vars.enable_video || osd_vars.enable_wfbng ) {
// stats height
Expand Down Expand Up @@ -108,9 +108,9 @@ void modeset_paint_buffer(struct modeset_buf *buf) {
}
avg_bw = avg_bw / avg_cnt;
if (avg_bw < 1000) {
sprintf(msg, "%.2f Kbps", avg_bw / 125 );
sprintf(msg, "%.2f Kbps", avg_bw / 85 );
} else {
sprintf(msg, "%.2f Mbps", avg_bw / 125000 );
sprintf(msg, "%.2f Mbps", avg_bw / 85000 );
}
row_count++;
cairo_set_source_surface (cr, net_icon, osd_x+22, stats_top_margin+row_count*stats_row_height-19);
Expand Down Expand Up @@ -141,58 +141,19 @@ void modeset_paint_buffer(struct modeset_buf *buf) {
return;
}

cairo_set_source_rgba (cr, 255.0, 255.0, 255.0, 1);
cairo_set_source_rgba (cr, 0.0, 255.0, 255.0, 1);
// Mavlink elements
uint32_t x_center = buf->width / 2;
if (osd_vars.telemetry_level > 1){
// TODO(geehe) How to draw lines with cairo?
// // Artificial Horizon
// int32_t offset_pitch = osd_vars.telemetry_pitch * 4;
// int32_t offset_roll = osd_vars.telemetry_roll * 4;
// int32_t y_pos_left = ((int32_t)buf->height / 2 - 2 + offset_pitch + offset_roll);
// int32_t y_pos_right = ((int32_t)buf->height / 2 - 2 + offset_pitch - offset_roll);

// for (int i = 0; i < 4; i++) {
// if (y_pos_left > 0 && y_pos_left < buf->height &&
// y_pos_right > 0 && y_pos_right < buf->height) {
// //fbg_line(cr, x_center - 180, y_pos_left + i, x_center + 180, y_pos_right + i, 255, 255, 255);
// }
// }

// // Vertical Speedometer
// int32_t offset_vspeed = osd_vars.telemetry_vspeed * 5;
// int32_t y_pos_vspeed = ((int32_t)buf->height / 2 - offset_vspeed);
// for (int i = 0; i < 8; i++) {
// if (y_pos_vspeed > 0 && y_pos_vspeed < buf->height) {
// //fbg_line(cr, x_center + 242 + i, buf->height / 2, x_center + 242 + i, y_pos_vspeed, 255, 255, 255);
// }
// }

// for (int i = 0; i < 25; i++) {
// uint32_t width = (i == 12) ? 10 : 0;

// // fbg_line(cr, x_center - 240 - width,
// // buf->height / 2 - 120 + i * 10, x_center - 220,
// // buf->height / 2 - 120 + i * 10, 255, 255, 255);
// // fbg_line(cr, x_center - 240 - width,
// // buf->height / 2 - 120 + i * 10 + 1, x_center - 220,
// // buf->height / 2 - 120 + i * 10 + 1, 255, 255, 255);

// // fbg_line(cr, x_center + 220, buf->height / 2 - 120 + i * 10,
// // x_center + 240 + width, buf->height / 2 - 120 + i * 10, 255, 255, 255);
// // fbg_line(cr, x_center + 220, buf->height / 2 - 120 + i * 10 + 1,
// // x_center + 240 + width, buf->height / 2 - 120 + i * 10 + 1, 255, 255, 255);
// }

// OSD telemetry
sprintf(msg, "ALT:%.00fM", osd_vars.telemetry_altitude);
cairo_move_to(cr, x_center + (20) + 260, buf->height / 2 - 8);
cairo_move_to(cr, x_center + (20) + 260, buf->height - 60);
cairo_show_text(cr, msg);
sprintf(msg, "SPD:%.00fKM/H", osd_vars.telemetry_gspeed);
cairo_move_to(cr, x_center - (16 * 3) - 360, buf->height / 2 - 8);
cairo_move_to(cr, x_center - 350, buf->height - 60);
cairo_show_text(cr, msg);
sprintf(msg, "VSPD:%.00fM/S", osd_vars.telemetry_vspeed);
cairo_move_to(cr, x_center + (20) + 260, buf->height / 2 + 22);
cairo_move_to(cr, x_center + (20) + 260, buf->height - 30);
cairo_show_text(cr, msg);
}

Expand All @@ -208,7 +169,10 @@ void modeset_paint_buffer(struct modeset_buf *buf) {
sprintf(msg, "THR:%.00f%%", osd_vars.telemetry_throttle);
cairo_move_to(cr, 40, buf->height - 120);
cairo_show_text(cr, msg);

sprintf(msg, "TEMP:%.00fC", osd_vars.telemetry_raw_imu/100);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you indicate that this is the AIR Temp ?

cairo_move_to(cr, 40, buf->height - 150);
cairo_show_text(cr, msg);

if (osd_vars.telemetry_level > 1){
sprintf(msg, "SATS:%.00f", osd_vars.telemetry_sats);
cairo_move_to(cr,buf->width - 140, buf->height - 30);
Expand Down Expand Up @@ -255,58 +219,14 @@ void modeset_paint_buffer(struct modeset_buf *buf) {
cairo_move_to(cr, x_center - 350, buf->height - 30);
cairo_show_text(cr, msg);
}

sprintf(msg, "RSSI:%.00f", osd_vars.telemetry_rssi);
cairo_move_to(cr, x_center - 50, buf->height - 30);
cairo_show_text(cr, msg);

// Print rate stats
struct timespec current_timestamp;
if (!clock_gettime(CLOCK_MONOTONIC_COARSE, &current_timestamp)) {
double interval = getTimeInterval(&current_timestamp, &last_timestamp);
if (osd_vars.telemetry_arm > 1700){
seconds = seconds + interval;
}
if (interval > 1) {
last_timestamp = current_timestamp;
rx_rate = ((float)stats_rx_bytes+(((float)stats_rx_bytes*25)/100)) / 1024.0f * 8;
stats_rx_bytes = 0;
}
}

char hud_frames_rx[32];
if (osd_vars.telemetry_level > 1){
cairo_move_to(cr, x_center - strlen(hud_frames_rx) / 2 * 16, 40);
cairo_show_text(cr, hud_frames_rx);
} else {
cairo_move_to(cr, buf->width - 300, buf->height - 60);
cairo_show_text(cr, hud_frames_rx);
sprintf(msg, "TIME:%.2d:%.2d", minutes,seconds);
cairo_move_to(cr, buf->width - 300, buf->height - 90);
cairo_show_text(cr, msg);
if(seconds > 59){
seconds = 0;
++minutes;
}
if(minutes > 59){
seconds = 0;
minutes = 0;
}
}
float percent = rx_rate / (1024 * 10);
if (percent > 1) {
percent = 1;
}

uint32_t width = (strlen(hud_frames_rx) * 16) * percent;
if (osd_vars.telemetry_level > 1){
cairo_set_source_rgba(cr, 255, 255, 255, 0.8); // R, G, B, A
cairo_rectangle(cr, x_center - strlen(hud_frames_rx) / 2 * 16, 64, width, 8);
} else {
cairo_set_source_rgba(cr, 255, 255, 255, 0.8); // R, G, B, A
cairo_rectangle(cr, buf->width - 300, buf->height - 36, width, 8);
}
cairo_fill(cr);
cairo_fill(cr);
}

int osd_thread_signal;
Expand Down
1 change: 1 addition & 0 deletions osd.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct osd_vars {
float telemetry_vspeed;
float telemetry_rssi;
float telemetry_throttle;
float telemetry_raw_imu;
float telemetry_resolution;
float telemetry_arm;
float armed;
Expand Down