diff --git a/release/files_common b/release/files_common index d219cbf56e..a4bb01062c 100644 --- a/release/files_common +++ b/release/files_common @@ -307,7 +307,8 @@ selfdrive/proclogd/SConscript selfdrive/proclogd/proclogd.cc selfdrive/loggerd/SConscript -selfdrive/loggerd/encoder.[c,h] +selfdrive/loggerd/encoder.h +selfdrive/loggerd/encoder.cc selfdrive/loggerd/frame_logger.h selfdrive/loggerd/logger.cc selfdrive/loggerd/logger.h diff --git a/selfdrive/loggerd/SConscript b/selfdrive/loggerd/SConscript index f0577ec11c..3765d064f9 100644 --- a/selfdrive/loggerd/SConscript +++ b/selfdrive/loggerd/SConscript @@ -2,11 +2,11 @@ Import('env', 'arch', 'cereal', 'messaging', 'common', 'visionipc') src = ['loggerd.cc', 'logger.cc'] libs = ['zmq', 'capnp', 'kj', 'z', - 'avformat', 'avcodec', 'swscale', 'avutil', - 'yuv', 'bz2', common, cereal, messaging, visionipc] + 'avformat', 'avcodec', 'swscale', 'avutil', + 'yuv', 'bz2', common, cereal, messaging, visionipc] if arch in ["aarch64", "larch64"]: - src += ['encoder.c'] + src += ['encoder.cc'] libs += ['OmxVenc', 'OmxCore'] if arch == "aarch64": libs += ['cutils'] diff --git a/selfdrive/loggerd/encoder.c b/selfdrive/loggerd/encoder.cc similarity index 94% rename from selfdrive/loggerd/encoder.c rename to selfdrive/loggerd/encoder.cc index 91b9dc8df5..3232453289 100644 --- a/selfdrive/loggerd/encoder.c +++ b/selfdrive/loggerd/encoder.cc @@ -17,8 +17,6 @@ #include -//#include - #include #include "common/mutex.h" @@ -27,9 +25,12 @@ #include "encoder.h" -//#define ALOG(...) __android_log_print(ANDROID_LOG_VERBOSE, "omxapp", ##__VA_ARGS__) - // encoder: lossey codec using hardware hevc + + + +// ***** OMX callback functions ***** + static void wait_for_state(EncoderState *s, OMX_STATETYPE state) { pthread_mutex_lock(&s->state_lock); while (s->state != state) { @@ -40,14 +41,14 @@ static void wait_for_state(EncoderState *s, OMX_STATETYPE state) { static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data) { - EncoderState *s = app_data; + EncoderState *s = (EncoderState*)app_data; switch (event) { case OMX_EventCmdComplete: assert(data1 == OMX_CommandStateSet); LOG("set state event 0x%x", data2); pthread_mutex_lock(&s->state_lock); - s->state = data2; + s->state = (OMX_STATETYPE)data2; pthread_cond_broadcast(&s->state_cv); pthread_mutex_unlock(&s->state_lock); break; @@ -66,24 +67,17 @@ static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, O static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer) { - EncoderState *s = app_data; - // printf("empty_buffer_done\n"); - + EncoderState *s = (EncoderState*)app_data; queue_push(&s->free_in, (void*)buffer); - return OMX_ErrorNone; } - static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer) { - EncoderState *s = app_data; - // printf("fill_buffer_done\n"); - + EncoderState *s = (EncoderState*)app_data; queue_push(&s->done_out, (void*)buffer); - return OMX_ErrorNone; } @@ -166,6 +160,9 @@ static const char* omx_color_fomat_name(uint32_t format) { } } + +// ***** encoder functions ***** + void encoder_init(EncoderState *s, const char* filename, int width, int height, int fps, int bitrate, bool h265, bool downscale) { int err; @@ -182,9 +179,9 @@ void encoder_init(EncoderState *s, const char* filename, int width, int height, if (downscale) { s->downscale = true; - s->y_ptr2 = malloc(s->width*s->height); - s->u_ptr2 = malloc(s->width*s->height/4); - s->v_ptr2 = malloc(s->width*s->height/4); + s->y_ptr2 = (uint8_t *)malloc(s->width*s->height); + s->u_ptr2 = (uint8_t *)malloc(s->width*s->height/4); + s->v_ptr2 = (uint8_t *)malloc(s->width*s->height/4); } s->segment = -1; @@ -242,9 +239,6 @@ void encoder_init(EncoderState *s, const char* filename, int width, int height, assert(err == OMX_ErrorNone); s->num_in_bufs = in_port.nBufferCountActual; - // printf("in width: %d, stride: %d\n", - // in_port.format.video.nFrameWidth, in_port.format.video.nStride); - // setup output port OMX_PARAM_PORTDEFINITIONTYPE out_port = {0}; @@ -355,14 +349,14 @@ void encoder_init(EncoderState *s, const char* filename, int width, int height, err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL); assert(err == OMX_ErrorNone); - s->in_buf_headers = calloc(s->num_in_bufs, sizeof(OMX_BUFFERHEADERTYPE*)); + s->in_buf_headers = (OMX_BUFFERHEADERTYPE **)calloc(s->num_in_bufs, sizeof(OMX_BUFFERHEADERTYPE*)); for (int i=0; inum_in_bufs; i++) { err = OMX_AllocateBuffer(s->handle, &s->in_buf_headers[i], PORT_INDEX_IN, s, in_port.nBufferSize); assert(err == OMX_ErrorNone); } - s->out_buf_headers = calloc(s->num_out_bufs, sizeof(OMX_BUFFERHEADERTYPE*)); + s->out_buf_headers = (OMX_BUFFERHEADERTYPE **)calloc(s->num_out_bufs, sizeof(OMX_BUFFERHEADERTYPE*)); for (int i=0; inum_out_bufs; i++) { err = OMX_AllocateBuffer(s->handle, &s->out_buf_headers[i], PORT_INDEX_OUT, s, out_port.nBufferSize); @@ -395,7 +389,7 @@ static void handle_out_buf(EncoderState *s, OMX_BUFFERHEADERTYPE *out_buf) { if (out_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { if (s->codec_config_len < out_buf->nFilledLen) { - s->codec_config = realloc(s->codec_config, out_buf->nFilledLen); + s->codec_config = (uint8_t *)realloc(s->codec_config, out_buf->nFilledLen); } s->codec_config_len = out_buf->nFilledLen; memcpy(s->codec_config, buf_data, out_buf->nFilledLen); @@ -412,7 +406,7 @@ static void handle_out_buf(EncoderState *s, OMX_BUFFERHEADERTYPE *out_buf) { if (s->remuxing) { if (!s->wrote_codec_config && s->codec_config_len > 0) { if (s->codec_ctx->extradata_size < s->codec_config_len) { - s->codec_ctx->extradata = realloc(s->codec_ctx->extradata, s->codec_config_len + AV_INPUT_BUFFER_PADDING_SIZE); + s->codec_ctx->extradata = (uint8_t *)realloc(s->codec_ctx->extradata, s->codec_config_len + AV_INPUT_BUFFER_PADDING_SIZE); } s->codec_ctx->extradata_size = s->codec_config_len; memcpy(s->codec_ctx->extradata, s->codec_config, s->codec_config_len); @@ -434,7 +428,9 @@ static void handle_out_buf(EncoderState *s, OMX_BUFFERHEADERTYPE *out_buf) { av_init_packet(&pkt); pkt.data = buf_data; pkt.size = out_buf->nFilledLen; - pkt.pts = pkt.dts = av_rescale_q_rnd(out_buf->nTimeStamp, in_timebase, s->ofmt_ctx->streams[0]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + + enum AVRounding rnd = static_cast(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + pkt.pts = pkt.dts = av_rescale_q_rnd(out_buf->nTimeStamp, in_timebase, s->ofmt_ctx->streams[0]->time_base, rnd); pkt.duration = av_rescale_q(50*1000, in_timebase, s->ofmt_ctx->streams[0]->time_base); if (out_buf->nFlags & OMX_BUFFERFLAG_SYNCFRAME) { @@ -478,7 +474,7 @@ int encoder_encode_frame(EncoderState *s, // this sometimes freezes... put it outside the encoder lock so we can still trigger rotates... // THIS IS A REALLY BAD IDEA, but apparently the race has to happen 30 times to trigger this //pthread_mutex_unlock(&s->lock); - OMX_BUFFERHEADERTYPE* in_buf = queue_pop(&s->free_in); + OMX_BUFFERHEADERTYPE* in_buf = (OMX_BUFFERHEADERTYPE *)queue_pop(&s->free_in); //pthread_mutex_lock(&s->lock); // if (s->rotating) { @@ -507,12 +503,12 @@ int encoder_encode_frame(EncoderState *s, s->u_ptr2, s->width/2, s->v_ptr2, s->width/2, s->width, s->height, - kFilterNone); + libyuv::kFilterNone); y_ptr = s->y_ptr2; u_ptr = s->u_ptr2; v_ptr = s->v_ptr2; } - err = I420ToNV12(y_ptr, s->width, + err = libyuv::I420ToNV12(y_ptr, s->width, u_ptr, s->width/2, v_ptr, s->width/2, in_y_ptr, in_y_stride, @@ -532,7 +528,7 @@ int encoder_encode_frame(EncoderState *s, // pump output while (true) { - OMX_BUFFERHEADERTYPE *out_buf = queue_try_pop(&s->done_out); + OMX_BUFFERHEADERTYPE *out_buf = (OMX_BUFFERHEADERTYPE *)queue_try_pop(&s->done_out); if (!out_buf) { break; } @@ -620,7 +616,7 @@ void encoder_close(EncoderState *s) { if (s->dirty) { // drain output only if there could be frames in the encoder - OMX_BUFFERHEADERTYPE* in_buf = queue_pop(&s->free_in); + OMX_BUFFERHEADERTYPE* in_buf = (OMX_BUFFERHEADERTYPE *)queue_pop(&s->free_in); in_buf->nFilledLen = 0; in_buf->nOffset = 0; in_buf->nFlags = OMX_BUFFERFLAG_EOS; @@ -630,7 +626,7 @@ void encoder_close(EncoderState *s) { assert(err == OMX_ErrorNone); while (true) { - OMX_BUFFERHEADERTYPE *out_buf = queue_pop(&s->done_out); + OMX_BUFFERHEADERTYPE *out_buf = (OMX_BUFFERHEADERTYPE *)queue_pop(&s->done_out); handle_out_buf(s, out_buf); @@ -650,8 +646,8 @@ void encoder_close(EncoderState *s) { fclose(s->of); } unlink(s->lock_path); - s->open = false; } + s->open = false; pthread_mutex_unlock(&s->lock); } @@ -712,19 +708,6 @@ void encoder_destroy(EncoderState *s) { #if 0 -// cd one/selfdrive/visiond -// clang -// -fPIC -pie -// -std=gnu11 -O2 -g -// -o encoder -// -I ~/one/selfdrive -// -I ~/one/phonelibs/openmax/include -// -I ~/one/phonelibs/libyuv/include -// -lOmxVenc -lOmxCore -llog -// encoder.c -// buffering.c -// -L ~/one/phonelibs/libyuv/lib -l:libyuv.a - int main() { int err; diff --git a/selfdrive/loggerd/encoder.h b/selfdrive/loggerd/encoder.h index 8036162b24..0baabd1496 100644 --- a/selfdrive/loggerd/encoder.h +++ b/selfdrive/loggerd/encoder.h @@ -1,23 +1,20 @@ -#ifndef ENCODER_H -#define ENCODER_H +#pragma once #include #include #include #include - #include -#include - -#include "common/cqueue.h" -#include "common/visionipc.h" -#ifdef __cplusplus extern "C" { -#endif + #include +} -typedef struct EncoderState { +#include "common/cqueue.h" +#include "visionipc.h" + +struct EncoderState { pthread_mutex_t lock; int width, height, fps; const char* path; @@ -65,7 +62,7 @@ typedef struct EncoderState { bool downscale; uint8_t *y_ptr2, *u_ptr2, *v_ptr2; -} EncoderState; +}; void encoder_init(EncoderState *s, const char* filename, int width, int height, int fps, int bitrate, bool h265, bool downscale); int encoder_encode_frame(EncoderState *s, @@ -76,9 +73,3 @@ void encoder_open(EncoderState *s, const char* path); void encoder_rotate(EncoderState *s, const char* new_path, int new_segment); void encoder_close(EncoderState *s); void encoder_destroy(EncoderState *s); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/selfdrive/loggerd/loggerd.cc b/selfdrive/loggerd/loggerd.cc index a66a06831a..b689d1a97d 100644 --- a/selfdrive/loggerd/loggerd.cc +++ b/selfdrive/loggerd/loggerd.cc @@ -4,12 +4,10 @@ #include #include #include -#include #include #include -#include -#include #include +#include #include #include @@ -46,15 +44,14 @@ #include "encoder.h" #endif -#define MAIN_BITRATE 5000000 -#define QCAM_BITRATE 128000 -#define MAIN_FPS 20 +constexpr int MAIN_BITRATE = 5000000; +constexpr int MAIN_FPS = 20; #ifndef QCOM2 -#define MAX_CAM_IDX LOG_CAMERA_ID_DCAMERA -#define DCAM_BITRATE 2500000 +constexpr int MAX_CAM_IDX = LOG_CAMERA_ID_DCAMERA; +constexpr int DCAM_BITRATE = 2500000; #else -#define MAX_CAM_IDX LOG_CAMERA_ID_ECAMERA -#define DCAM_BITRATE MAIN_BITRATE +constexpr int MAX_CAM_IDX = LOG_CAMERA_ID_ECAMERA; +constexpr int DCAM_BITRATE = MAIN_BITRATE; #endif #define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead @@ -93,7 +90,7 @@ LogCameraInfo cameras_logged[LOG_CAMERA_ID_MAX] = { [LOG_CAMERA_ID_QCAMERA] = { .filename = "qcamera.ts", .fps = MAIN_FPS, - .bitrate = QCAM_BITRATE, + .bitrate = 128000, .is_h265 = false, .downscale = true, #ifndef QCOM2 @@ -105,12 +102,12 @@ LogCameraInfo cameras_logged[LOG_CAMERA_ID_MAX] = { }; +namespace { + constexpr int SEGMENT_LENGTH = 60; const char* LOG_ROOT = "/data/media/0/realdata"; -namespace { - double randrange(double a, double b) __attribute__((unused)); double randrange(double a, double b) { static std::mt19937 gen(millis_since_boot()); @@ -137,14 +134,16 @@ public: void waitLogThread() { std::unique_lock lk(fid_lock); - while (stream_frame_id > log_frame_id //if the log camera is older, wait for it to catch up. + while (stream_frame_id > log_frame_id // if the log camera is older, wait for it to catch up. && (stream_frame_id - log_frame_id) < 8 // but if its too old then there probably was a discontinuity (visiond restarted) && !do_exit) { cv.wait(lk); } } - void cancelWait() { cv.notify_one(); } + void cancelWait() { + cv.notify_one(); + } void setStreamFrameId(uint32_t frame_id) { fid_lock.lock(); @@ -161,10 +160,11 @@ public: } void rotate() { - if (!enabled) { return; } - std::unique_lock lk(fid_lock); - should_rotate = true; - last_rotate_frame_id = stream_frame_id; + if (enabled) { + std::unique_lock lk(fid_lock); + should_rotate = true; + last_rotate_frame_id = stream_frame_id; + } } void finish_rotate() { @@ -183,11 +183,12 @@ struct LoggerdState { char segment_path[4096]; int rotate_segment; pthread_mutex_t rotate_lock; + + // video encders int num_encoder; std::atomic rotate_seq_id; std::atomic should_close; std::atomic finish_close; - RotateState rotate_state[LOG_CAMERA_ID_MAX-1]; }; LoggerdState s; @@ -204,13 +205,12 @@ void encoder_thread(int cam_idx) { std::vector encoders; - int encoder_segment = -1; - int cnt = 0; pthread_mutex_lock(&s.rotate_lock); int my_idx = s.num_encoder; s.num_encoder += 1; pthread_mutex_unlock(&s.rotate_lock); + int cnt = 0; LoggerHandle *lh = NULL; while (!do_exit) { @@ -222,6 +222,7 @@ void encoder_thread(int cam_idx) { continue; } + // init encoders if (encoders.empty()) { LOGD("encoder init %dx%d", buf_info.width, buf_info.height); @@ -252,8 +253,8 @@ void encoder_thread(int cam_idx) { //double msdiff = (double) diff / 1000000.0; // printf("logger latency to tsEof: %f\n", msdiff); - { // all the rotation stuff - + // all the rotation stuff + { pthread_mutex_lock(&s.rotate_lock); pthread_mutex_unlock(&s.rotate_lock); @@ -268,8 +269,9 @@ void encoder_thread(int cam_idx) { rotate_state.last_rotate_frame_id = extra.frame_id - 1; rotate_state.initialized = true; } - - while (s.rotate_seq_id != my_idx && !do_exit) { usleep(1000); } + + // poll for our turn + while (s.rotate_seq_id != my_idx && !do_exit) util::sleep_for(10); LOGW("camera %d rotate encoder to %s.", cam_idx, s.segment_path); for (auto &e : encoders) { @@ -277,7 +279,6 @@ void encoder_thread(int cam_idx) { } s.rotate_seq_id = (my_idx + 1) % s.num_encoder; - encoder_segment = s.rotate_segment; if (lh) { lh_close(lh); } @@ -287,11 +288,11 @@ void encoder_thread(int cam_idx) { s.should_close += 1; pthread_mutex_unlock(&s.rotate_lock); - while(s.should_close > 0 && s.should_close < s.num_encoder && !do_exit) { usleep(1000); } + while(s.should_close > 0 && s.should_close < s.num_encoder && !do_exit) util::sleep_for(10); pthread_mutex_lock(&s.rotate_lock); s.should_close = s.should_close == s.num_encoder ? 1 - s.num_encoder : s.should_close + 1; - + for (auto &e : encoders) { encoder_close(e); encoder_open(e, e->next_path); @@ -302,7 +303,8 @@ void encoder_thread(int cam_idx) { s.finish_close += 1; pthread_mutex_unlock(&s.rotate_lock); - while(s.finish_close > 0 && s.finish_close < s.num_encoder && !do_exit) { usleep(1000); } + // wait for all to finish + while(s.finish_close > 0 && s.finish_close < s.num_encoder && !do_exit) util::sleep_for(10); s.finish_close = 0; rotate_state.finish_rotate(); @@ -338,7 +340,7 @@ void encoder_thread(int cam_idx) { #ifdef QCOM2 eidx.setType(cereal::EncodeIndex::Type::FULL_H_E_V_C); #else - eidx.setType(cam_idx == LOG_CAMERA_ID_DCAMERA ? cereal::EncodeIndex::Type::FRONT:cereal::EncodeIndex::Type::FULL_H_E_V_C); + eidx.setType(cam_idx == LOG_CAMERA_ID_DCAMERA ? cereal::EncodeIndex::Type::FRONT : cereal::EncodeIndex::Type::FULL_H_E_V_C); #endif eidx.setEncodeId(cnt); @@ -384,9 +386,9 @@ kj::Array gen_init_data() { MessageBuilder msg; auto init = msg.initEvent().initInitData(); - if (file_exists("/EON")) + if (file_exists("/EON")) { init.setDeviceType(cereal::InitData::DeviceType::NEO); - else if (file_exists("/TICI")) { + } else if (file_exists("/TICI")) { init.setDeviceType(cereal::InitData::DeviceType::TICI); } else { init.setDeviceType(cereal::InitData::DeviceType::PC); @@ -426,31 +428,15 @@ kj::Array gen_init_data() { if (dongle_id) { init.setDongleId(std::string(dongle_id)); } + init.setDirty(!getenv("CLEAN")); - const char* clean = getenv("CLEAN"); - if (!clean) { - init.setDirty(true); - } + // log params Params params = Params(); - - std::vector git_commit = params.read_db_bytes("GitCommit"); - if (git_commit.size() > 0) { - init.setGitCommit(capnp::Text::Reader(git_commit.data(), git_commit.size())); - } - - std::vector git_branch = params.read_db_bytes("GitBranch"); - if (git_branch.size() > 0) { - init.setGitBranch(capnp::Text::Reader(git_branch.data(), git_branch.size())); - } - - std::vector git_remote = params.read_db_bytes("GitRemote"); - if (git_remote.size() > 0) { - init.setGitRemote(capnp::Text::Reader(git_remote.data(), git_remote.size())); - } - + init.setGitCommit(params.get("GitCommit")); + init.setGitBranch(params.get("GitBranch")); + init.setGitRemote(params.get("GitRemote")); init.setPassive(params.read_db_bool("Passive")); { - // log params std::map params_map; params.read_db_all(¶ms_map); auto lparams = init.initParams().initEntries(params_map.size()); @@ -513,11 +499,8 @@ static void bootlog() { } int main(int argc, char** argv) { - int err; -#ifdef QCOM setpriority(PRIO_PROCESS, 0, -12); -#endif if (argc > 1 && strcmp(argv[1], "--bootlog") == 0) { bootlog(); @@ -528,6 +511,7 @@ int main(int argc, char** argv) { if (getenv("LOGGERD_TEST")) { segment_length = atoi(getenv("LOGGERD_SEGMENT_LENGTH")); } + bool record_front = true; #ifndef QCOM2 record_front = Params().read_db_bool("RecordFront"); @@ -576,6 +560,7 @@ int main(int argc, char** argv) { s.num_encoder = 0; pthread_mutex_init(&s.rotate_lock, NULL); + // TODO: create these threads dynamically on frame packet presence std::vector encoder_threads; #ifndef DISABLE_ENCODER encoder_threads.push_back(std::thread(encoder_thread, LOG_CAMERA_ID_FCAMERA)); @@ -600,7 +585,11 @@ int main(int argc, char** argv) { double last_rotate_tms = millis_since_boot(); double last_camera_seen_tms = millis_since_boot(); while (!do_exit) { + // TODO: fix msgs from the first poll getting dropped + // poll for new messages on all sockets for (auto sock : poller->poll(1000)) { + + // drain socket Message * last_msg = nullptr; while (!do_exit) { Message * msg = sock->receive(true); @@ -612,21 +601,20 @@ int main(int argc, char** argv) { QlogState& qs = qlog_states[sock]; logger_log(&s.logger, (uint8_t*)msg->getData(), msg->getSize(), qs.counter == 0); - if (qs.counter != -1) { - //printf("%p: %d/%d\n", socks[i], qlog_counter[socks[i]], qlog_freqs[socks[i]]); qs.counter = (qs.counter + 1) % qs.freq; } + bytes_count += msg->getSize(); msg_count++; } if (last_msg) { int fpkt_id = -1; - for (int cid=0;cid<=MAX_CAM_IDX;cid++) { + for (int cid = 0; cid <=MAX_CAM_IDX; cid++) { if (sock == s.rotate_state[cid].fpkt_sock) {fpkt_id=cid; break;} } - if (fpkt_id>=0) { + if (fpkt_id >= 0) { // track camera frames to sync to encoder // only process last frame const uint8_t* data = (uint8_t*)last_msg->getData(); @@ -649,51 +637,51 @@ int main(int argc, char** argv) { } last_camera_seen_tms = millis_since_boot(); } - delete last_msg; } + delete last_msg; } - double ts = seconds_since_boot(); - double tms = millis_since_boot(); - - bool new_segment = false; - + bool new_segment = s.logger.part == -1; if (s.logger.part > -1) { - new_segment = true; + double tms = millis_since_boot(); if (tms - last_camera_seen_tms <= NO_CAMERA_PATIENCE && s.num_encoder > 0) { - for (int cid=0;cid<=MAX_CAM_IDX;cid++) { + new_segment = true; + for (auto &r : s.rotate_state) { // this *should* be redundant on tici since all camera frames are synced - new_segment &= (((s.rotate_state[cid].stream_frame_id >= s.rotate_state[cid].last_rotate_frame_id + segment_length * MAIN_FPS) && - (!s.rotate_state[cid].should_rotate) && (s.rotate_state[cid].initialized)) || - (!s.rotate_state[cid].enabled)); + new_segment &= (((r.stream_frame_id >= r.last_rotate_frame_id + segment_length * MAIN_FPS) && + (!r.should_rotate) && (r.initialized)) || + (!r.enabled)); #ifndef QCOM2 break; // only look at fcamera frame id if not QCOM2 #endif } } else { - new_segment &= tms - last_rotate_tms > segment_length * 1000; - if (new_segment) { LOGW("no camera packet seen. auto rotated"); } + if (tms - last_rotate_tms > segment_length * 1000) { + new_segment = true; + LOGW("no camera packet seen. auto rotated"); + } } - } else if (s.logger.part == -1) { - // always starts first segment immediately - new_segment = true; } + // rotate to new segment if (new_segment) { pthread_mutex_lock(&s.rotate_lock); last_rotate_tms = millis_since_boot(); - err = logger_next(&s.logger, LOG_ROOT, s.segment_path, sizeof(s.segment_path), &s.rotate_segment); + int err = logger_next(&s.logger, LOG_ROOT, s.segment_path, sizeof(s.segment_path), &s.rotate_segment); assert(err == 0); - if (s.logger.part == 0) { LOGW("logging to %s", s.segment_path); } + if (s.logger.part == 0) { + LOGW("logging to %s", s.segment_path); + } LOGW("rotated to %s", s.segment_path); - // rotate the encoders - for (int cid=0;cid<=MAX_CAM_IDX;cid++) { s.rotate_state[cid].rotate(); } + // rotate encoders + for (auto &r : s.rotate_state) r.rotate(); pthread_mutex_unlock(&s.rotate_lock); } - if ((msg_count%1000) == 0) { + if ((msg_count % 1000) == 0) { + double ts = seconds_since_boot(); LOGD("%lu messages, %.2f msg/sec, %.2f KB/sec", msg_count, msg_count*1.0/(ts-start_ts), bytes_count*0.001/(ts-start_ts)); } } diff --git a/selfdrive/loggerd/tests/test_loggerd.py b/selfdrive/loggerd/tests/test_loggerd.py index 96719dce6e..66745cfd17 100755 --- a/selfdrive/loggerd/tests/test_loggerd.py +++ b/selfdrive/loggerd/tests/test_loggerd.py @@ -49,14 +49,14 @@ class TestLoggerd(unittest.TestCase): def _check_init_data(self, msgs): msg = msgs[0] - assert msg.which() == 'initData' + self.assertEqual(msg.which(), 'initData') def _check_sentinel(self, msgs, route): start_type = SentinelType.startOfRoute if route else SentinelType.startOfSegment - assert msgs[1].sentinel.type == start_type + self.assertTrue(msgs[1].sentinel.type == start_type) end_type = SentinelType.endOfRoute if route else SentinelType.endOfSegment - assert msgs[-1].sentinel.type == end_type + self.assertTrue(msgs[-1].sentinel.type == end_type) def test_init_data_values(self): os.environ["CLEAN"] = random.choice(["0", "1"]) @@ -74,19 +74,19 @@ class TestLoggerd(unittest.TestCase): lr = list(LogReader(str(self._gen_bootlog()))) initData = lr[0].initData - assert initData.dirty != bool(os.environ["CLEAN"]) - assert initData.dongleId == os.environ["DONGLE_ID"] - assert initData.version == VERSION + self.assertTrue(initData.dirty != bool(os.environ["CLEAN"])) + self.assertEqual(initData.dongleId, os.environ["DONGLE_ID"]) + self.assertEqual(initData.version, VERSION) if os.path.isfile("/proc/cmdline"): with open("/proc/cmdline") as f: - assert list(initData.kernelArgs) == f.read().strip().split(" ") + self.assertEqual(list(initData.kernelArgs), f.read().strip().split(" ")) with open("/proc/version") as f: - assert initData.kernelVersion == f.read() + self.assertEqual(initData.kernelVersion, f.read()) for _, k, v in fake_params: - assert getattr(initData, k) == v + self.assertEqual(getattr(initData, k), v) def test_bootlog(self): # generate bootlog with fake launch log @@ -118,7 +118,7 @@ class TestLoggerd(unittest.TestCase): val = b"" if path.is_file(): val = open(path, "rb").read() - assert getattr(boot, field) == val + self.assertEqual(getattr(boot, field), val) def test_qlog(self): qlog_services = [s for s in CEREAL_SERVICES if service_list[s].decimation is not None] @@ -164,11 +164,11 @@ class TestLoggerd(unittest.TestCase): if s in no_qlog_services: # check services with no specific decimation aren't in qlog - assert recv_cnt == 0, f"got {recv_cnt} {s} msgs in qlog" + self.assertEqual(recv_cnt, 0, f"got {recv_cnt} {s} msgs in qlog") else: # check logged message count matches decimation expected_cnt = len(msgs) // service_list[s].decimation - assert recv_cnt == expected_cnt, f"expected {expected_cnt} msgs for {s}, got {recv_cnt}" + self.assertEqual(recv_cnt, expected_cnt, f"expected {expected_cnt} msgs for {s}, got {recv_cnt}") def test_rlog(self): services = random.sample(CEREAL_SERVICES, random.randint(5, 10)) @@ -204,7 +204,7 @@ class TestLoggerd(unittest.TestCase): for m in lr: sent = sent_msgs[m.which()].pop(0) sent.clear_write_flag() - assert sent.to_bytes() == m.as_builder().to_bytes() + self.assertEqual(sent.to_bytes(), m.as_builder().to_bytes()) if __name__ == "__main__":