Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mkapp/app/setting.ini
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ format_ts=true
osd=true
audio=true
audio_source=0
naming=0

[image]
oled=8
Expand Down
1 change: 1 addition & 0 deletions src/core/dvr.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ static void dvr_update_record_conf() {

ini_putl("record", "audio", g_setting.record.audio, REC_CONF);
dvr_select_audio_source(g_setting.record.audio_source);
ini_putl("record", "naming", g_setting.record.naming, REC_CONF);
}

void dvr_cmd(osd_dvr_cmd_t cmd) {
Expand Down
2 changes: 2 additions & 0 deletions src/core/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const setting_t g_setting_defaults = {
.osd = true,
.audio = true,
.audio_source = SETTING_RECORD_AUDIO_SOURCE_MIC,
.naming = SETTING_NAMING_CONTIGUOUS,
},
.image = {
.oled = 8,
Expand Down Expand Up @@ -384,6 +385,7 @@ void settings_load(void) {
g_setting.record.osd = settings_get_bool("record", "osd", g_setting_defaults.record.osd);
g_setting.record.audio = settings_get_bool("record", "audio", g_setting_defaults.record.audio);
g_setting.record.audio_source = ini_getl("record", "audio_source", g_setting_defaults.record.audio_source, SETTING_INI);
g_setting.record.naming = ini_getl("record", "naming", g_setting_defaults.record.naming, SETTING_INI);

// image
g_setting.image.oled = ini_getl("image", "oled", g_setting_defaults.image.oled, SETTING_INI);
Expand Down
6 changes: 6 additions & 0 deletions src/core/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,18 @@ typedef enum {
SETTING_RECORD_AUDIO_SOURCE_AV_IN = 2
} setting_record_audio_source_t;

typedef enum {
SETTING_NAMING_CONTIGUOUS,
SETTING_NAMING_DATE
} setting_record_naming_t;

typedef struct {
bool mode_manual;
bool format_ts;
bool osd;
bool audio;
setting_record_audio_source_t audio_source;
setting_record_naming_t naming;
} setting_record_t;

typedef struct {
Expand Down
13 changes: 10 additions & 3 deletions src/driver/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
#include <unistd.h>

#include <log/log.h>
#include <minIni.h>

#include "core/settings.h"
#include "ui/page_common.h"

/**
* Constants
Expand Down Expand Up @@ -173,19 +175,24 @@ void rtc_tv2rd(const struct timeval *tv, struct rtc_date *rd) {
}

/**
* Initialize both the hardware ans system clocks.
* Initialize both the hardware and system clocks.
*/
void rtc_init() {
struct rtc_date rd;
rtc_get_clock(&rd);

// Has time has accumulated since the
// the installation of the battery?
// Has time accumulated since the
// installation of the battery?
g_rtc_has_battery = rd.year > 1970;

LOGI("rtc_init %s detected a battery",
(g_rtc_has_battery ? "has" : "has NOT"));

if (!g_rtc_has_battery) {
g_setting.record.naming = SETTING_NAMING_CONTIGUOUS;
ini_putl("record", "naming", g_setting.record.naming, SETTING_INI);
}

if (rd.year == 1970) {
LOGI("rtc_init updating both clocks via settings");
rd.year = g_setting.clock.year;
Expand Down
5 changes: 5 additions & 0 deletions src/record/confparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define KEY_SIZE "size"
#define KEY_FULL "full"
#define KEY_AUDIO "audio"
#define KEY_NAMING "naming"

#define KEY_WIDTH "width"
#define KEY_HEIGHT "height"
Expand Down Expand Up @@ -426,6 +427,10 @@ void conf_loadRecordParams(char* confFile, RecordParams_t* para)
}
}

lValue = ini_getl(SEC_RECORD, KEY_NAMING, NAMING_CONTIGUOUS, confFile);
lValue = check_set(lValue, NAMING_CONTIGUOUS, NAMING_DATE);
para->fileNaming = lValue;

lValue = ini_getl(SEC_RECORD, KEY_DURATION, REC_packDURATION, confFile);
lValue = check_set(lValue, REC_minDURATION, REC_maxDURATION);
para->packDuration = lValue * 60*1000; //minutes to millseconds
Expand Down
40 changes: 38 additions & 2 deletions src/record/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ void record_dumpParams(RecordParams_t* params)
LOGD("full: %d MB", params->minDiskSize);
LOGD("duration: %d minutes", params->packDuration/(60*1000));
LOGD("audio : %s", params->enableAudio ? "yes" : "no");
LOGD("naming : %s", params->fileNaming == NAMING_DATE ? "Date" : "Contiguous");
}

void record_dumpVeParams(VencParams_t* params)
Expand Down Expand Up @@ -348,8 +349,20 @@ int record_start(RecordContext_t* recCtx)
LOGE("get sps failed: %x", ret);
}

char dateString[16];
char sFile[256];
REC_filePathGet(sFile, recCtx->params.packPath, REC_packPREFIX, nbFileIndex, recCtx->params.packType);
switch (recCtx->params.fileNaming) {
case NAMING_CONTIGUOUS:
REC_filePathGet(sFile, recCtx->params.packPath, REC_packPREFIX, nbFileIndex, recCtx->params.packType);
break;
case NAMING_DATE: {
const time_t t = time(0);
const struct tm* date = localtime(&t);
sprintf(dateString, "%04d%02d%02d-%02d%02d%02d", date->tm_year + 1900, date->tm_mon + 1, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec);
sprintf(sFile, "%s%s.%s", recCtx->params.packPath, dateString, recCtx->params.packType);
break;
}
}

FFPack_t* ff = ffpack_openFile(sFile, NULL);
if( ff == NULL ) {
Expand Down Expand Up @@ -403,6 +416,22 @@ int record_start(RecordContext_t* recCtx)
recCtx->fpsStatus.tickFps = recCtx->tickBegin;
recCtx->fpsStatus.nbFrames= 0;

// Add metadata to the program context
// Note: ts container does not support date so this will only be visible when
// recording to mp4 container format
{
const time_t t = time(0);
const struct tm * date = localtime(&t);
char localDateString[20];
char fileName[64];

strcpy(fileName, strrchr(sFile, '/') + 1);
av_dict_set(&ff->ofmtContext->metadata, "title", fileName, 0);

sprintf(localDateString, "%04d-%02d-%02d %02d:%02d:%02d", date->tm_year + 1900, date->tm_mon + 1, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec);
av_dict_set(&ff->ofmtContext->metadata, "date", localDateString, 0);
}

ret = ffpack_start(ff);
if( ret != SUCCESS ) {
goto failed;
Expand All @@ -424,7 +453,14 @@ int record_start(RecordContext_t* recCtx)
record_saveStatus(recCtx, REC_statusRun);
recCtx->nbFileIndex++;

REC_filePathGet(sFile, recCtx->params.packPath, REC_packPREFIX, nbFileIndex, REC_packSnapTYPE);
switch (recCtx->params.fileNaming) {
case NAMING_CONTIGUOUS:
REC_filePathGet(sFile, recCtx->params.packPath, REC_packPREFIX, nbFileIndex, REC_packSnapTYPE);
break;
case NAMING_DATE:
sprintf(sFile, "%s%s.%s", recCtx->params.packPath, dateString, REC_packSnapTYPE);
break;
}
ret = record_takePicture(recCtx, sFile);

record_dumpViParams(&viParams);
Expand Down
6 changes: 6 additions & 0 deletions src/record/record.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ typedef enum
REC_statusBut,
} RecordStatus_e;

typedef enum {
NAMING_CONTIGUOUS,
NAMING_DATE
} FileNaming_t;

typedef struct
{
char diskPath[MAX_pathLEN/2];
Expand All @@ -50,6 +55,7 @@ typedef struct
uint32_t minDiskSize;
uint64_t packSize;
bool enableAudio;
FileNaming_t fileNaming;
} RecordParams_t;

typedef struct
Expand Down
17 changes: 13 additions & 4 deletions src/ui/page_playback.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ static void show_pb_item(uint8_t pos, char *label) {
lv_label_set_text(pb_ui[pos]._label, label);
lv_obj_clear_flag(pb_ui[pos]._label, LV_OBJ_FLAG_HIDDEN);

const lv_coord_t labelPosX = pb_ui[pos].x + (ITEM_PREVIEW_W - lv_txt_get_width(label, strlen(label) - 2, &lv_font_montserrat_26, 0, 0)) / 2;
const lv_coord_t labelPosY = pb_ui[pos].y + ITEM_PREVIEW_H + 10;
lv_obj_set_pos(pb_ui[pos]._label, labelPosX, labelPosY);
lv_obj_set_pos(pb_ui[pos]._arrow, labelPosX - lv_obj_get_width(pb_ui[pos]._arrow) - 5, labelPosY);

sprintf(fname, "%s/%s." REC_packJPG, TMP_DIR, label);
if (fs_file_exists(fname))
sprintf(fname, "A:%s/%s." REC_packJPG, TMP_DIR, label);
Expand Down Expand Up @@ -201,6 +206,9 @@ static int walk_sdcard() {
}

media_file_node_t *pnode = &media_db.list[media_db.count];
ZeroMemory(pnode->filename, sizeof(pnode->filename));
ZeroMemory(pnode->label, sizeof(pnode->label));
ZeroMemory(pnode->ext, sizeof(pnode->ext));
strcpy(pnode->filename, in_file->d_name);
strncpy(pnode->label, in_file->d_name, dot - in_file->d_name);
strcpy(pnode->ext, dot + 1);
Expand Down Expand Up @@ -314,11 +322,12 @@ static void mark_video_file(int const seq) {
const int index = find_next_available_hot_index();

char cmd[256];
int length = sprintf(cmd, "mv %s%s ", MEDIA_FILES_DIR, pnode->filename);
REC_filePathGet(&cmd[length], MEDIA_FILES_DIR, REC_packHotPREFIX, index, pnode->ext);
char newLabel[68];
sprintf(newLabel, "%s%s", REC_hotPREFIX, pnode->label);

sprintf(cmd, "mv %s%s %s%s.%s", MEDIA_FILES_DIR, pnode->filename, MEDIA_FILES_DIR, newLabel, pnode->ext);
system_exec(cmd);
length = sprintf(cmd, "mv %s%s." REC_packJPG " ", MEDIA_FILES_DIR, pnode->label);
REC_filePathGet(&cmd[length], MEDIA_FILES_DIR, REC_packHotPREFIX, index, REC_packJPG);
sprintf(cmd, "mv %s%s." REC_packJPG " %s%s." REC_packJPG, MEDIA_FILES_DIR, pnode->label, MEDIA_FILES_DIR, newLabel);
system_exec(cmd);

walk_sdcard();
Expand Down
80 changes: 49 additions & 31 deletions src/ui/page_record.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,36 @@

#include "../core/common.hh"
#include "core/settings.h"
#include "driver/rtc.h"
#include "page_common.h"
#include "ui/ui_style.h"

static btn_group_t btn_group0;
static btn_group_t btn_group1;
static btn_group_t btn_group2;
static btn_group_t btn_group3;
static btn_group_t btn_group4;
static btn_group_t btn_group_record_mode;
static btn_group_t btn_group_format;
static btn_group_t btn_group_record_osd;
static btn_group_t btn_group_record_audio;
static btn_group_t btn_group_audio_source;
static btn_group_t btn_group_file_naming;

static lv_coord_t col_dsc[] = {160, 200, 200, 160, 120, 120, LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, LV_GRID_TEMPLATE_LAST};

static void update_visibility() {
btn_group_enable(&btn_group4, btn_group3.current == 0);
btn_group_enable(&btn_group_audio_source, btn_group_record_audio.current == 0);

if (btn_group3.current == 0) {
if (btn_group_record_audio.current == 0) {
lv_obj_add_flag(pp_record.p_arr.panel[4], FLAG_SELECTABLE);
} else {
lv_obj_clear_flag(pp_record.p_arr.panel[4], FLAG_SELECTABLE);
}

btn_group_enable(&btn_group_file_naming, rtc_has_battery() == 0);

if (rtc_has_battery() == 0) {
lv_obj_add_flag(pp_record.p_arr.panel[5], FLAG_SELECTABLE);
} else {
lv_obj_clear_flag(pp_record.p_arr.panel[5], FLAG_SELECTABLE);
}
}

static lv_obj_t *page_record_create(lv_obj_t *parent, panel_arr_t *arr) {
Expand Down Expand Up @@ -53,18 +63,20 @@ static lv_obj_t *page_record_create(lv_obj_t *parent, panel_arr_t *arr) {

create_select_item(arr, cont);

create_btn_group_item(&btn_group0, cont, 2, "Record Mode", "Auto", "Manual", "", "", 0);
create_btn_group_item(&btn_group1, cont, 2, "Record Format", "MP4", "TS", "", "", 1);
create_btn_group_item(&btn_group2, cont, 2, "Record OSD", "Yes", "No", "", "", 2);
create_btn_group_item(&btn_group3, cont, 2, "Record Audio", "Yes", "No", "", "", 3);
create_btn_group_item(&btn_group4, cont, 3, "Audio Source", "Mic", "Line In", "A/V In", "", 4);
create_label_item(cont, "< Back", 1, 5, 1);

btn_group_set_sel(&btn_group0, g_setting.record.mode_manual ? 1 : 0);
btn_group_set_sel(&btn_group1, g_setting.record.format_ts ? 1 : 0);
btn_group_set_sel(&btn_group2, g_setting.record.osd ? 0 : 1);
btn_group_set_sel(&btn_group3, g_setting.record.audio ? 0 : 1);
btn_group_set_sel(&btn_group4, g_setting.record.audio_source);
create_btn_group_item(&btn_group_record_mode, cont, 2, "Record Mode", "Auto", "Manual", "", "", 0);
create_btn_group_item(&btn_group_format, cont, 2, "Record Format", "MP4", "TS", "", "", 1);
create_btn_group_item(&btn_group_record_osd, cont, 2, "Record OSD", "Yes", "No", "", "", 2);
create_btn_group_item(&btn_group_record_audio, cont, 2, "Record Audio", "Yes", "No", "", "", 3);
create_btn_group_item(&btn_group_audio_source, cont, 3, "Audio Source", "Mic", "Line In", "A/V In", "", 4);
create_btn_group_item(&btn_group_file_naming, cont, 2, "Naming Scheme", "Digits", "Date", "", "", 5);
create_label_item(cont, "< Back", 1, 6, 1);

btn_group_set_sel(&btn_group_record_mode, g_setting.record.mode_manual ? 1 : 0);
btn_group_set_sel(&btn_group_format, g_setting.record.format_ts ? 1 : 0);
btn_group_set_sel(&btn_group_record_osd, g_setting.record.osd ? 0 : 1);
btn_group_set_sel(&btn_group_record_audio, g_setting.record.audio ? 0 : 1);
btn_group_set_sel(&btn_group_audio_source, g_setting.record.audio_source);
btn_group_set_sel(&btn_group_file_naming, g_setting.record.naming);

lv_obj_t *label2 = lv_label_create(cont);
lv_label_set_text(label2, "MP4 format requires properly closing files or the files will be corrupt. \nTS format is highly recommended.");
Expand All @@ -74,7 +86,7 @@ static lv_obj_t *page_record_create(lv_obj_t *parent, panel_arr_t *arr) {
lv_obj_set_style_pad_top(label2, 12, 0);
lv_label_set_long_mode(label2, LV_LABEL_LONG_WRAP);
lv_obj_set_grid_cell(label2, LV_GRID_ALIGN_START, 1, 4,
LV_GRID_ALIGN_START, 6, 3);
LV_GRID_ALIGN_START, 7, 3);

update_visibility();

Expand All @@ -83,37 +95,43 @@ static lv_obj_t *page_record_create(lv_obj_t *parent, panel_arr_t *arr) {

static void page_record_on_click(uint8_t key, int sel) {
if (sel == 0) {
btn_group_toggle_sel(&btn_group0);
g_setting.record.mode_manual = btn_group_get_sel(&btn_group0);
btn_group_toggle_sel(&btn_group_record_mode);
g_setting.record.mode_manual = btn_group_get_sel(&btn_group_record_mode);
settings_put_bool("record", "mode_manual", g_setting.record.mode_manual);
} else if (sel == 1) {
btn_group_toggle_sel(&btn_group1);
g_setting.record.format_ts = btn_group_get_sel(&btn_group1);
btn_group_toggle_sel(&btn_group_format);
g_setting.record.format_ts = btn_group_get_sel(&btn_group_format);
settings_put_bool("record", "format_ts", g_setting.record.format_ts);
if (g_setting.record.format_ts)
ini_puts("record", "type", "ts", REC_CONF);
else
ini_puts("record", "type", "mp4", REC_CONF);
} else if (sel == 2) {
btn_group_toggle_sel(&btn_group2);
g_setting.record.osd = !btn_group_get_sel(&btn_group2);
btn_group_toggle_sel(&btn_group_record_osd);
g_setting.record.osd = !btn_group_get_sel(&btn_group_record_osd);
settings_put_bool("record", "osd", g_setting.record.osd);
} else if (sel == 3) {
btn_group_toggle_sel(&btn_group3);
g_setting.record.audio = !btn_group_get_sel(&btn_group3);
btn_group_toggle_sel(&btn_group_record_audio);
g_setting.record.audio = !btn_group_get_sel(&btn_group_record_audio);
settings_put_bool("record", "audio", g_setting.record.audio);
update_visibility();
} else if (sel == 4) {
btn_group_toggle_sel(&btn_group4);
g_setting.record.audio_source = btn_group_get_sel(&btn_group4);
btn_group_toggle_sel(&btn_group_audio_source);
g_setting.record.audio_source = btn_group_get_sel(&btn_group_audio_source);
ini_putl("record", "audio_source", g_setting.record.audio_source, SETTING_INI);
} else if (sel == 5) {
if (rtc_has_battery() == 0) {
btn_group_toggle_sel(&btn_group_file_naming);
g_setting.record.naming = btn_group_get_sel(&btn_group_file_naming);
ini_putl("record", "naming", g_setting.record.naming, SETTING_INI);
}
}
}

page_pack_t pp_record = {
.p_arr = {
.cur = 0,
.max = 6,
.max = 7,
},
.name = "Record Option",
.create = page_record_create,
Expand Down