diff --git a/src/fio-ml.c b/src/fio-ml.c index 4e1b39896..245eb51ca 100644 --- a/src/fio-ml.c +++ b/src/fio-ml.c @@ -9,18 +9,18 @@ #define CARD_DRIVE_INIT(_letter, _type) { .drive_letter = _letter, .type = _type, .cluster_size = 0, .free_space_raw = 0, .file_number = 0, .folder_number = 0, } -static struct card_info available_cards[] = { CARD_DRIVE_INIT("A","CF"), CARD_DRIVE_INIT("B", "SD"), CARD_DRIVE_INIT("C","EXT") }; +static struct card_info possible_cards[] = { CARD_DRIVE_INIT("A","CF"), CARD_DRIVE_INIT("B", "SD"), CARD_DRIVE_INIT("C","EXT") }; #if defined(CONFIG_CF_SLOT) -static struct card_info * ML_CARD = &available_cards[CARD_A]; +static struct card_info * ML_CARD = &possible_cards[CARD_A]; #else -static struct card_info * ML_CARD = &available_cards[CARD_B]; +static struct card_info * ML_CARD = &possible_cards[CARD_B]; #endif #if defined(CONFIG_DUAL_SLOT) || defined(CONFIG_CF_SLOT) -static struct card_info * SHOOTING_CARD = &available_cards[CARD_A]; +static struct card_info * SHOOTING_CARD = &possible_cards[CARD_A]; #else -static struct card_info * SHOOTING_CARD = &available_cards[CARD_B]; +static struct card_info * SHOOTING_CARD = &possible_cards[CARD_B]; #endif // File I/O wrappers for handling the dual card slot on 5D3 @@ -61,7 +61,34 @@ struct card_info* get_shooting_card() struct card_info* get_card(int cardId) { ASSERT(cardId >= 0 && cardId < 3); - return &available_cards[cardId]; + return &possible_cards[cardId]; +} + +struct actual_cards_t *get_actual_cards() +{ + static struct actual_cards_t actual_cards = {0, {NULL, NULL}}; + // init the actual cards the first time: + if (actual_cards.count == 0) + { + for (int i = 0; i < 2; i++) + { + struct card_info *p_card_info = get_card(i); + // check if drive is accessible: + char drive[8]; + snprintf(drive, 7, "%s:/", p_card_info->drive_letter); + if (!is_dir(drive)) + { + continue; + } + // reference active cards and increment actual card count: + actual_cards.infos[actual_cards.count++] = p_card_info; + // compute card total space: + p_card_info->free_space_MB = ((uint64_t)get_free_space_32k(p_card_info)) >> 5; + uint64_t dcim_size_MB = get_folder_size_MB(get_dcim_dir_ex(p_card_info)); + p_card_info->total_space_MB = p_card_info->free_space_MB + dcim_size_MB; + } + } + return &actual_cards; } int get_free_space_32k(const struct card_info* card) @@ -69,6 +96,13 @@ int get_free_space_32k(const struct card_info* card) return card->free_space_raw * (card->cluster_size>>10) / (32768>>10); } +void update_free_space(struct card_info *_p_card_info) +{ + // approximate free space based of total space and current DCIM folder content size: + uint64_t dcim_size_MB = get_folder_size_MB(get_dcim_dir_ex(_p_card_info)); + _p_card_info->free_space_MB = _p_card_info->total_space_MB - dcim_size_MB; +} + static CONFIG_INT("card.test", card_test_enabled, 1); static CONFIG_INT("card.force_type", card_force_type, 0); @@ -151,8 +185,8 @@ void _card_tweaks() #ifdef CONFIG_5D3 if (card_test_enabled) { - if (available_cards[CARD_A].free_space_raw > 10) card_test(&available_cards[CARD_A]); - if (available_cards[CARD_B].free_space_raw > 10) card_test(&available_cards[CARD_B]); + if (possible_cards[CARD_A].free_space_raw > 10) card_test(&possible_cards[CARD_A]); + if (possible_cards[CARD_B].free_space_raw > 10) card_test(&possible_cards[CARD_B]); /* if it reaches this point, the cards are OK */ card_test_enabled = 0; @@ -223,17 +257,17 @@ void _find_ml_card() if (ml_cf && !ml_sd) { - ML_CARD = &available_cards[CARD_A]; + ML_CARD = &possible_cards[CARD_A]; } else if (!ml_cf && ml_sd) { - ML_CARD = &available_cards[CARD_B]; + ML_CARD = &possible_cards[CARD_B]; } else if (ml_cf && ml_sd) { /* still ambiguity? */ /* we know Canon loads autoexec.bin from the SD card first */ - ML_CARD = &available_cards[CARD_B]; + ML_CARD = &possible_cards[CARD_B]; startup_warning("ML on both cards, loading from SD."); } else @@ -245,9 +279,9 @@ void _find_ml_card() PROP_HANDLER(PROP_CARD_SELECT) { int card_select = buf[0] - 1; - if (card_select >= 0 && card_select < COUNT(available_cards)) + if (card_select >= 0 && card_select < COUNT(possible_cards)) { - SHOOTING_CARD = &available_cards[card_select]; + SHOOTING_CARD = &possible_cards[card_select]; return; } ASSERT(0); @@ -255,62 +289,62 @@ PROP_HANDLER(PROP_CARD_SELECT) PROP_HANDLER(PROP_CLUSTER_SIZE_A) { - available_cards[CARD_A].cluster_size = buf[0]; + possible_cards[CARD_A].cluster_size = buf[0]; } PROP_HANDLER(PROP_CLUSTER_SIZE_B) { - available_cards[CARD_B].cluster_size = buf[0]; + possible_cards[CARD_B].cluster_size = buf[0]; } PROP_HANDLER(PROP_CLUSTER_SIZE_C) { - available_cards[CARD_C].cluster_size = buf[0]; + possible_cards[CARD_C].cluster_size = buf[0]; } PROP_HANDLER(PROP_FREE_SPACE_A) { - available_cards[CARD_A].free_space_raw = buf[0]; + possible_cards[CARD_A].free_space_raw = buf[0]; } PROP_HANDLER(PROP_FREE_SPACE_B) { - available_cards[CARD_B].free_space_raw = buf[0]; + possible_cards[CARD_B].free_space_raw = buf[0]; } PROP_HANDLER(PROP_FREE_SPACE_C) { - available_cards[CARD_C].free_space_raw = buf[0]; + possible_cards[CARD_C].free_space_raw = buf[0]; } PROP_HANDLER(PROP_FILE_NUMBER_A) { - available_cards[CARD_A].file_number = buf[0]; + possible_cards[CARD_A].file_number = buf[0]; } PROP_HANDLER(PROP_FILE_NUMBER_B) { - available_cards[CARD_B].file_number = buf[0]; + possible_cards[CARD_B].file_number = buf[0]; } PROP_HANDLER(PROP_FILE_NUMBER_C) { - available_cards[CARD_C].file_number = buf[0]; + possible_cards[CARD_C].file_number = buf[0]; } PROP_HANDLER(PROP_FOLDER_NUMBER_A) { - available_cards[CARD_A].folder_number = buf[0]; + possible_cards[CARD_A].folder_number = buf[0]; } PROP_HANDLER(PROP_FOLDER_NUMBER_B) { - available_cards[CARD_B].folder_number = buf[0]; + possible_cards[CARD_B].folder_number = buf[0]; } PROP_HANDLER(PROP_FOLDER_NUMBER_C) { - available_cards[CARD_C].folder_number = buf[0]; + possible_cards[CARD_C].folder_number = buf[0]; } PROP_HANDLER(PROP_DCIM_DIR_SUFFIX) @@ -323,12 +357,38 @@ const char * get_dcim_dir_suffix() return dcim_dir_suffix; } -const char* get_dcim_dir() +const char *get_dcim_dir_ex(struct card_info *_p_card_info) { - snprintf(dcim_dir, sizeof(dcim_dir), "%s:/DCIM/%03d%s", SHOOTING_CARD->drive_letter, SHOOTING_CARD->folder_number, dcim_dir_suffix); + snprintf(dcim_dir, sizeof(dcim_dir), "%s:/DCIM/%03d%s", _p_card_info->drive_letter, _p_card_info->folder_number, dcim_dir_suffix); return dcim_dir; } +const char* get_dcim_dir() +{ + return get_dcim_dir_ex(SHOOTING_CARD); +} + +uint64_t get_folder_size_MB(const char *_folder) +{ + struct fio_file file; + struct fio_dirent *dirent = FIO_FindFirstEx(_folder, &file); + if (IS_ERROR(dirent)) + { + return 0; + } + uint64_t cumulated_size_KB = 0; + do + { + if (file.name[0] == 0 || file.name[0] == '.' || (file.mode & ATTR_DIRECTORY)) + { + continue; + } + cumulated_size_KB += ((uint64_t)file.size) >> 10; + } while (FIO_FindNextEx(dirent, &file) == 0); + FIO_FindClose(dirent); + return cumulated_size_KB >> 10; +} + static void fixup_filename(char* new_filename, const char* old_filename, int size) { #define IS_IN_ML_DIR(filename) (strncmp("ML/", filename, 3) == 0) @@ -822,8 +882,8 @@ static void fio_init() #endif #ifdef CARD_A_MAKER - available_cards[CARD_A].maker = (char*) CARD_A_MAKER; - available_cards[CARD_A].model = (char*) CARD_A_MODEL; + possible_cards[CARD_A].maker = (char*) CARD_A_MAKER; + possible_cards[CARD_A].model = (char*) CARD_A_MODEL; #endif } diff --git a/src/fio-ml.h b/src/fio-ml.h index 150ff0338..9e6f91ba1 100644 --- a/src/fio-ml.h +++ b/src/fio-ml.h @@ -16,6 +16,14 @@ struct card_info { int folder_number; char * maker; /* only for some cameras; NULL otherwise */ char * model; + uint64_t total_space_MB; // initial estimation of total card space (MB) + uint64_t free_space_MB; // dynamic free space (MB) estimation +}; + +struct actual_cards_t +{ + int count; // number of actual active cards + struct card_info *infos[2]; // pointers to valid card_info }; struct card_info * get_ml_card(); @@ -23,8 +31,12 @@ struct card_info * get_shooting_card(); struct card_info * get_card(int cardId); +struct actual_cards_t *get_actual_cards(); + int get_free_space_32k (const struct card_info * card); +void update_free_space(struct card_info *_p_card_info); + /* returns true if the specified file or directory exists */ int is_file(const char* path); int is_dir(const char* path); @@ -153,9 +165,13 @@ size_t read_file( const char * filename, void * buf, size_t size); uint8_t* read_entire_file(const char * filename, int* buf_size); +const char *get_dcim_dir_ex(struct card_info *_p_card_info); const char* get_dcim_dir(); const char* get_dcim_dir_suffix(); +// compute the cumulated file size (MB) of a given folder +uint64_t get_folder_size_MB(const char *_folder); + extern int __attribute__((format(printf,2,3))) my_fprintf( FILE * file, diff --git a/src/lens.c b/src/lens.c index e56b552ec..c2a909e89 100644 --- a/src/lens.c +++ b/src/lens.c @@ -2935,25 +2935,40 @@ static LVINFO_UPDATE_FUNC(fps_update) static LVINFO_UPDATE_FUNC(free_space_update) { - LVINFO_BUFFER(8); - + LVINFO_BUFFER(14); + // worst case "SD:999 CF:999" + if (RECORDING) { /* leave space for the recording indicators */ return; } - int free_space_32k = get_free_space_32k(get_shooting_card()); + // get actual card list: + struct actual_cards_t *p_actual_cards = get_actual_cards(); - int fsg = free_space_32k >> 15; - int fsgr = free_space_32k - (fsg << 15); - int fsgf = (fsgr * 10) >> 15; + // update free space: + for (int i = 0; i < p_actual_cards->count; i++) + { + update_free_space(p_actual_cards->infos[i]); + } - snprintf(buffer, sizeof(buffer), - "%d.%dGB", - fsg, - fsgf - ); + // setup display for 1 slot: + struct card_info *p_card_1 = p_actual_cards->infos[0]; + int free_space_card_1_GB = (int)p_card_1->free_space_MB >> 10; + free_space_card_1_GB = (free_space_card_1_GB > 999) ? 999 : free_space_card_1_GB; + if (p_actual_cards->count == 1) + { + snprintf(buffer, sizeof(buffer), "%s:%d", p_card_1->type, free_space_card_1_GB); + } + // setup display for 2 slots: + else + { + struct card_info *p_card_2 = p_actual_cards->infos[1]; + int free_space_card_2_GB = (int)p_card_2->free_space_MB >> 10; + free_space_card_2_GB = (free_space_card_2_GB > 999) ? 999 : free_space_card_2_GB; + snprintf(buffer, sizeof(buffer), "%s:%d %s:%d", p_card_1->type, free_space_card_1_GB, p_card_2->type, free_space_card_2_GB); + } } static LVINFO_UPDATE_FUNC(mode_update) @@ -3299,7 +3314,7 @@ static struct lvinfo_item info_items[] = { .name = "Temperature", .which_bar = LV_TOP_BAR_ONLY, .update = temp_update, - .priority = 1, + .priority = -1, }, { .name = "MVI number",