EDIT : I found the issue, wrong filename size (exceed 8 character)
Now it works.
What I have for now : dual DNG shot in liveView, with iso and shutter changed, but the result seems to be two times the same image.
This code crash the camera some times.
There seems to be buffer rewriting, how can I save the first image buffer during the second shot ?
Also, sometimes, I record only 33kb files, I don't know why.
My edited code from the silent module :
/** Silent pictures **/
#include <module.h>
#include <dryos.h>
#include <bmp.h>
#include <menu.h>
#include <config.h>
#include <property.h>
#include <raw.h>
#include <shoot.h>
#include <zebra.h>
#include <beep.h>
#include <lens.h>
#include <focus.h>
#include <string.h>
#include <battery.h>
#include <powersave.h>
#include "../lv_rec/lv_rec.h"
#include "../mlv_rec/mlv.h"
static uint64_t ret_0_long() { return 0; }
extern WEAK_FUNC(ret_0) void display_filter_get_buffers(uint32_t** src_buf, uint32_t** dst_buf);
extern WEAK_FUNC(ret_0) void mlv_fill_rtci(mlv_rtci_hdr_t *hdr, uint64_t start_timestamp);
extern WEAK_FUNC(ret_0) void mlv_fill_expo(mlv_expo_hdr_t *hdr, uint64_t start_timestamp);
extern WEAK_FUNC(ret_0) void mlv_fill_lens(mlv_lens_hdr_t *hdr, uint64_t start_timestamp);
extern WEAK_FUNC(ret_0) void mlv_fill_idnt(mlv_idnt_hdr_t *hdr, uint64_t start_timestamp);
extern WEAK_FUNC(ret_0) void mlv_fill_wbal(mlv_wbal_hdr_t *hdr, uint64_t start_timestamp);
extern WEAK_FUNC(ret_0) void mlv_fill_styl(mlv_styl_hdr_t *hdr, uint64_t start_timestamp);
extern WEAK_FUNC(ret_0_long) uint64_t mlv_generate_guid();
extern WEAK_FUNC(ret_0) void mlv_init_fileheader(mlv_file_hdr_t *hdr);
extern WEAK_FUNC(ret_0) void mlv_set_type(mlv_hdr_t *hdr, char *type);
extern WEAK_FUNC(ret_0_long) uint64_t mlv_set_timestamp(mlv_hdr_t *hdr, uint64_t start);
extern WEAK_FUNC(ret_0) int GetBatteryLevel();
extern WEAK_FUNC(ret_0) int GetBatteryTimeRemaining();
extern WEAK_FUNC(ret_0) int GetBatteryDrainRate();
//~ #define FEATURE_SILENT_PIC_RAW
static CONFIG_INT( "silent.pic.iso", silent_pic_recovery_iso, 0);
static CONFIG_INT( "silent.pic.shutter", silent_pic_recovery_shutter, 0);
static CONFIG_INT( "silent.pic", silent_pic_enabled, 0 );
static CONFIG_INT( "silent.pic.mode", silent_pic_mode, 5 );
static CONFIG_INT( "silent.pic.slitscan.mode", silent_pic_slitscan_mode, 0 );
static CONFIG_INT( "silent.pic.file_format", silent_pic_file_format, 0 );
#define SILENT_PIC_MODE_SIMPLE 0
#define SILENT_PIC_MODE_BURST 1
#define SILENT_PIC_MODE_BURST_END_TRIGGER 2
#define SILENT_PIC_MODE_BEST_FOCUS 3
#define SILENT_PIC_MODE_SLITSCAN 4
#define SILENT_PIC_MODE_FULLRES 5
#define SILENT_PIC_FILE_FORMAT_DNG 0
#define SILENT_PIC_FILE_FORMAT_MLV 1
#define SILENT_PIC_MODE_SLITSCAN_SCAN_TTB 0 // top to bottom
#define SILENT_PIC_MODE_SLITSCAN_SCAN_BTT 1 // bottom to top
#define SILENT_PIC_MODE_SLITSCAN_SCAN_LTR 2 // left to right
#define SILENT_PIC_MODE_SLITSCAN_SCAN_RTL 3 // right to left
#define SILENT_PIC_MODE_SLITSCAN_CENTER_H 4 // center horizontal
//#define SILENT_PIC_MODE_SLITSCAN_CENTER_V 5 // center vertical
//static int silent_pic_mlv_available = 0;
//static mlv_file_hdr_t mlv_file_hdr;
//static uint64_t mlv_start_timestamp = 0;
static char image_file_name[100];
//static uint32_t mlv_max_filesize = 0xFFFFFFFF;
static int mlv_file_frame_number = 0;
static int long_exposure_fix_enabled = 0;
/* forward reference */
static struct menu_entry silent_menu[];
static int iso_original = 0;
static int shutter_original = 0;
static int new_iso = 0;
static int new_shutter = 0;
static MENU_UPDATE_FUNC(silent_pic_mode_update)
{
/* reveal options for the current shooting mode, if any */
// silent_menu[0].children[1].shidden =(silent_pic_mode != SILENT_PIC_MODE_SLITSCAN);
}
static MENU_UPDATE_FUNC(isocheck)
{
switch (silent_pic_recovery_iso)
{
case -12:
new_iso = ISO_100;
break;
case -11:
new_iso = ISO_125;
break;
case -10:
new_iso = ISO_160;
break;
case -9:
new_iso = ISO_200;
break;
case -8:
new_iso = ISO_250;
break;
case -7:
new_iso = ISO_320;
break;
case -6:
new_iso = ISO_400;
break;
case -5:
new_iso = ISO_500;
break;
case -4:
new_iso = ISO_640;
break;
case -3:
new_iso = ISO_800;
break;
case -2:
new_iso = ISO_1000;
break;
case -1:
new_iso = ISO_1250;
break;
case 0:
new_iso = ISO_1600;
break;
case 1:
new_iso = ISO_2000;
break;
case 2:
new_iso = ISO_2500;
break;
case 3:
new_iso = ISO_3200;
break;
case 4:
new_iso = ISO_4000;
break;
}
//bmp_printf(FONT_MED, 0, 0, "Iso debug : %d", silent_pic_recovery_iso);
bmp_printf(FONT_MED, 0, 0, "Iso chosen : %d", new_iso);
}
static MENU_UPDATE_FUNC(shuttercheck)
{
switch (silent_pic_recovery_shutter)
{
case -12:
new_shutter = SHUTTER_1_60;
break;
case -11:
new_shutter = SHUTTER_1_80;
break;
case -10:
new_shutter = SHUTTER_1_90;
break;
case -9:
new_shutter = SHUTTER_1_100;
break;
case -8:
new_shutter = SHUTTER_1_125;
break;
case -7:
new_shutter = SHUTTER_1_160;
break;
case -6:
new_shutter = SHUTTER_1_180;
break;
case -5:
new_shutter = SHUTTER_1_200;
break;
case -4:
new_shutter = SHUTTER_1_250;
break;
case -3:
new_shutter = SHUTTER_1_320;
break;
case -2:
new_shutter = SHUTTER_1_350;
break;
case -1:
new_shutter = SHUTTER_1_400;
break;
case 0:
new_shutter = SHUTTER_1_500;
break;
case 1:
new_shutter = SHUTTER_1_640;
break;
case 2:
new_shutter = SHUTTER_1_750;
break;
case 3:
new_shutter = SHUTTER_1_800;
break;
case 4:
new_shutter = SHUTTER_1_1000;
break;
case 5:
new_shutter = SHUTTER_1_1250;
break;
case 6:
new_shutter = SHUTTER_1_1500;
break;
case 7:
new_shutter = SHUTTER_1_1600;
break;
case 8:
new_shutter = SHUTTER_1_2000;
break;
case 9:
new_shutter = SHUTTER_1_2500;
break;
case 10:
new_shutter = SHUTTER_1_3000;
break;
case 11:
new_shutter = SHUTTER_1_3200;
break;
case 12:
new_shutter = SHUTTER_1_4000;
break;
}
//bmp_printf(FONT_MED, 0, 0, "Shutter debug : %d", silent_pic_recovery_shutter);
bmp_printf(FONT_MED, 0, 0, "Shutter chosen : %d", new_shutter);
}
static MENU_UPDATE_FUNC(silent_pic_display)
{
/* reset the MLV frame counter if we enter ML menu */
/* exception: don't reset if the intervalometer is running - we might want to change some settings on the fly */
if (!is_intervalometer_running())
{
mlv_file_frame_number = 0;
}
if (!silent_pic_enabled)
return;
//MENU_SET_VALUE("Full-res");
//MENU_SET_HELP("File format: 14-bit DNG, individual files.");
//MENU_APPEND_VALUE(", DNG");
if (silent_pic_mode == SILENT_PIC_MODE_FULLRES && (shooting_mode != SHOOTMODE_M || is_movie_mode()))
{
MENU_SET_WARNING(MENU_WARN_NOT_WORKING, "Full-res pictures only work in Manual (M) photo mode.");
}
//silent_pic_check_mlv(entry, info);
}
static char* silent_pic_get_name()
{
char *extension;
extension = "DNG";
int file_number = get_shooting_card()->file_number;
int is_mlv = (silent_pic_file_format == SILENT_PIC_FILE_FORMAT_MLV);
if (is_intervalometer_running() && !is_mlv)
{
char pattern[100];
snprintf(pattern, sizeof(pattern), "%s/%%08d.%s", get_dcim_dir(), 0, extension);
get_numbered_file_name(pattern, 99999999, image_file_name, sizeof(image_file_name));
}
else
{
char pattern[100];
snprintf(pattern, sizeof(pattern), "%s/%04d%%04d.%s", get_dcim_dir(), file_number, 0, extension);
get_numbered_file_name(pattern, 9999, image_file_name, sizeof(image_file_name));
}
bmp_printf(FONT_MED, 0, 37, "%s ", image_file_name);
return image_file_name;
}
static int silent_pic_save_file(struct raw_info * raw_info, int capture_time_ms)
{
char* filename = silent_pic_get_name();
int ok = save_dng(filename, raw_info);
if (!ok) bmp_printf( FONT_MED, 0, 83, "DNG save error (card full?)");
return ok;
}
static void show_battery_status()
{
if ((void*)&GetBatteryLevel == (void*)&ret_0)
{
return;
}
int l = GetBatteryLevel();
int r = GetBatteryTimeRemaining();
int d = GetBatteryDrainRate();
bmp_printf(FONT_MED, 0, 480 - font_med.height,
"Battery: %d%%, %dh%02dm, %d%%/h",
l, 0,
r / 3600, (r % 3600) / 60,
d, 0
);
}
/* FA test image code only looks at these 3 properties - doesn't know about auto ISO & stuff */
/* lens_info data may not be in sync, e.g. when using expo override */
/* so, check these props directly before taking a picture */
static PROP_INT(PROP_ISO, prop_iso);
static PROP_INT(PROP_SHUTTER, prop_shutter);
/* this will check (poll) if we are still in QR (or paused LV) mode, every 100ms,
* until preview_time expires or until you get out of QR, whichever happens first
* if we didn't leave QR mode, it will turn off the display
*/
static void display_off_if_qr_mode(int unused, int preview_time)
{
if (is_play_or_qr_mode() || LV_PAUSED)
{
if (preview_time > 0)
{
/* OK for now, re-check after 100ms */
delayed_call(100, display_off_if_qr_mode, (void*)(preview_time - 100));
}
else
{
/* preview_time expired */
display_off();
}
}
}
static uint32_t SLOWEST_SHUTTER = SHUTTER_15s;
static void long_exposure_fix()
{
unsigned shutter_old = lens_info.raw_shutter;
if (long_exposure_fix_enabled && shutter_old < SHUTTER_0s8)
{
unsigned shutter = SHUTTER_1_500;
prop_request_change_wait( PROP_SHUTTER, &shutter, 4, 100);
void* job = (void*) call("FA_CreateTestImage");
/* We need paused lv, otherwise the camera will freeze */
if (!LV_PAUSED && gui_state != GUISTATE_QR)
{
gui_uilock(UILOCK_EVERYTHING);
PauseLiveView();
}
call("FA_CaptureTestImage", job);
call("FA_DeleteTestImage", job);
prop_request_change_wait( PROP_SHUTTER, &shutter_old, 4, 100);
}
}
static int
silent_pic_take_fullres(int interactive)
{
int ok = 1;
/* get out of LiveView, but leave the shutter open */
PauseLiveView();
/* block all keys until finished, to avoid errors */
gui_uilock(UILOCK_EVERYTHING);
clrscr();
vram_clear_lv();
char* error_msg = 0;
if (shooting_mode != SHOOTMODE_M)
{
error_msg = "Manual (M) mode is required.";
goto err;
}
if (prop_iso == 0 || prop_shutter == 0)
{
error_msg = "Manual exposure is required.";
goto err;
}
/* there are problems with shutter speeds slower than 15 seconds */
/* (corrupted image and camera lockup, at least on 5D2 and 550D) */
if (prop_shutter < SLOWEST_SHUTTER)
{
static char expo_msg[50];
snprintf(expo_msg, sizeof(expo_msg), "Exposure too long (max %s).", lens_format_shutter(SLOWEST_SHUTTER));
error_msg = expo_msg;
goto err;
}
if (!can_use_raw_overlays_photo())
{
error_msg = "Set picture quality to RAW.";
goto err;
}
/* Canon photo taking code is busy? (may happen if you press the shutter fully) */
while (lens_info.job_state)
{
bmp_printf(FONT_MED, 0, 0, "Busy...");
msleep(10);
}
/* Are we still in paused LV mode? (QR is also allowed) */
if (!LV_PAUSED && gui_state != GUISTATE_QR)
{
goto err;
}
display_off();
/* we'll need these later */
struct JobClass * copy_job = 0;
void* copy_buf = 0;
struct JobClass * copy_job2 = 0;
void* copy_buf2 = 0;
/* from now on, we can no longer jump to "err" */
/*
* This enters factory testing mode (SRM_ChangeMemoryManagementForFactory),
* reads PROP_ISO, PROP_SHUTTER and PROP_APERTURE,
* and creates a "job" object (CreateSkeltonJob)
*/
struct JobClass * job = (void*) call("FA_CreateTestImage");
lens_info.job_state = 1;
info_led_on();
int t0 = get_ms_clock_value();
/*
* This one sets PROP_FA_ADJUST_FLAG to 4 (configures scsReleaseData for DARK_MEM1),
* then sends event 0 to SCS state (scsReleaseStart),
* then sends event 1 to SCS state (scsReleaseData),
* then resets PROP_FA_ADJUST_FLAG back to 0.
*
* The SCS state machine continues with scsDummyReadoutDone,
* scsCapReady, scsCapEnd and scsFinalReadoutDone.
*
* After that, raw image data will be written by CCDWriteEDmacCompleteCBR
* and available from RAW_PHOTO_EDMAC (defined in raw.c)
*/
call("FA_CaptureTestImage", job);
int t1 = get_ms_clock_value();
int capture_time = t1 - t0;
info_led_off();
lens_info.job_state = 0;
/* prepare to save the file */
struct raw_info local_raw_info = raw_info;
struct raw_info local_raw_info2 = raw_info;
/* DNG only: make a copy of the image, because save_dng will overwrite the contents of the raw buffer */
copy_job = (void*) call("FA_CreateTestImage");
copy_buf = (void*) call("FA_GetCrawBuf", copy_job);
if (!copy_buf)
{
bmp_printf(FONT_MED, 0, 0, "Memory error1");
goto cleanup;
}
//call("FA_DeleteTestImage", job);
//job = (void*) call("FA_CreateTestImage");
//Shot 1 finished
shutter_original = lens_info.raw_shutter;
iso_original = lens_info.raw_iso;
lens_set_rawiso(new_iso);
lens_set_rawshutter(new_shutter);
//Setting up new ISO value : silent_pic_recovery_iso
//bmp_printf(FONT_MED, 0, 0, "Shutter chosen : %d", shutter);
//Setting the previously calculated shutter time (wich would be short)
//Starting second shot
lens_info.job_state = 1;
info_led_on();
int t3 = get_ms_clock_value();
call("FA_CaptureTestImage", job);
int t2 = get_ms_clock_value();
int capture_time2 = t3 - t2;
info_led_off();
lens_info.job_state = 0;
//Ended shot
local_raw_info = raw_info;
/* DNG only: make a copy of the image, because save_dng will overwrite the contents of the raw buffer */
copy_job2 = (void*) call("FA_CreateTestImage");
copy_buf2 = (void*) call("FA_GetCrawBuf", copy_job2);
if (!copy_buf2)
{
bmp_printf(FONT_MED, 0, 0, "Memory error2");
goto cleanup;
}
/* even if we don't preview, we still have to update raw parameters */
raw_set_dirty();
/* fake a QR mode, so the raw backend knows what parameters to apply */
/* but do not notify others (triggering the property would freeze on some cameras) */
/* however this won't trigger ETTR & co (but you'll see a warning in the menu) */
int old_gui_state = gui_state;
gui_state = GUISTATE_QR;
ok = raw_update_params();
gui_state = old_gui_state;
if (!ok)
{
display_on();
msleep(100);
bmp_printf(FONT_MED, 0, 0, "Raw error");
goto cleanup;
}
/* save the raw image as DNG or MLV */
int save_time;
{
bmp_printf(FONT_MED, 0, 60, "Saving %d x %d...", local_raw_info.jpeg.width, local_raw_info.jpeg.height);
bmp_printf(FONT_MED, 0, 83, "Captured in %d ms.", capture_time);
int t0 = get_ms_clock_value();
if (copy_buf)
{
local_raw_info.buffer = copy_buf;
memcpy(local_raw_info.buffer, raw_info.buffer, local_raw_info.frame_size);
}
ok = silent_pic_save_file(&local_raw_info, capture_time);
//char* filename = silent_pic_get_name();
//int ok = save_dng(filename, &local_raw_info);
//if (!ok) bmp_printf( FONT_MED, 0, 83, "DNG1 save error (card full?)");
int t1 = get_ms_clock_value();
save_time = t1 - t0;
if (ok)
{
bmp_printf(FONT_MED, 0, 60, "Saved %d x %d (%d ms, %d MiB/s). ",
local_raw_info.jpeg.width, local_raw_info.jpeg.height,
save_time, (int)roundf(local_raw_info.frame_size * 1000.0f / (t1 - t0) / 1024.0f / 1024.0f)
);
}
}
//Savec Image 1
{
bmp_printf(FONT_MED, 0, 60, "Saving %d x %d...", local_raw_info.jpeg.width, local_raw_info.jpeg.height);
bmp_printf(FONT_MED, 0, 83, "Captured in %d ms.", capture_time2);
int t0 = get_ms_clock_value();
if (copy_buf2)
{
local_raw_info.buffer = copy_buf2;
memcpy(local_raw_info.buffer, raw_info.buffer, local_raw_info.frame_size);
}
ok = silent_pic_save_file(&local_raw_info, capture_time2);
//char* filename = silent_pic_get_name();
//int ok = save_dng(filename, &local_raw_info);
//if (!ok) bmp_printf( FONT_MED, 0, 83, "DNG1 save error (card full?)");
int t1 = get_ms_clock_value();
save_time = t1 - t0;
if (ok)
{
bmp_printf(FONT_MED, 0, 60, "Saved %d x %d (%d ms, %d MiB/s). ",
local_raw_info.jpeg.width, local_raw_info.jpeg.height,
save_time, (int)roundf(local_raw_info.frame_size * 1000.0f / (t1 - t0) / 1024.0f / 1024.0f)
);
}
}
lens_set_rawiso(iso_original);
lens_set_rawshutter(shutter_original);
bmp_printf(FONT_MED, 0, 106, "Long half-shutter will take another picture.");
int preview_delay = MAX(1000, image_review_time * 1000 - save_time);
delayed_call(100, display_off_if_qr_mode, (void*)preview_delay);
cleanup:
/*
* This deallocates the job object (DeleteSkeltonJob),
* and after the last job is deallocated, it gets out of factory mode
* (SRM_ChangeMemoryManagementForImage)
*/
call("FA_DeleteTestImage", job);
if (copy_job)
{
call("FA_DeleteTestImage", copy_job);
}
if (copy_job2)
{
call("FA_DeleteTestImage", copy_job2);
}
long_exposure_fix();
gui_uilock(UILOCK_NONE);
return ok;
err:
if (error_msg)
{
bmp_printf(FONT_MED, 0, 0, "%s", error_msg);
msleep(2000);
}
gui_uilock(UILOCK_NONE);
ResumeLiveView();
return 0;
}
static unsigned int
silent_pic_take(unsigned int interactive) // for remote release, set interactive=0
{
if (!silent_pic_enabled)
{
/* tell the photo taking backend that no custom picture was taken */
/* (so it should try another custom picture handler or a regular picture) */
return CBR_RET_CONTINUE;
}
int ok = 0;
/* in fullres mode, go to LiveView only if in normal photo mode */
/* if it's in QR or paused LV (most likely from previous silent picture), just stay there */
if (!lv && !LV_PAUSED && gui_state != GUISTATE_QR) force_liveview();
ok = silent_pic_take_fullres(interactive);
/* reset the powersave timer */
powersave_prolong();
return ok ? CBR_RET_STOP : CBR_RET_ERROR;
}
static unsigned int silent_pic_polling_cbr(unsigned int ctx)
{
if (!silent_pic_enabled)
return 0;
/* fullres silent pics only work in M mode,
* and they may screw up things if triggered while recording. */
if (silent_pic_mode == SILENT_PIC_MODE_FULLRES && (shooting_mode != SHOOTMODE_M || is_movie_mode()))
return 0;
static int silent_pic_countdown;
if (!display_idle())
{
silent_pic_countdown = 10;
}
else if (!get_halfshutter_pressed())
{
if (silent_pic_countdown)
silent_pic_countdown--;
}
if (lv && get_halfshutter_pressed())
{
/* half-shutter was pressed while in playback mode, for example */
if (silent_pic_countdown)
{
/* in this case, require a long press to trigger a new picture */
for (int i = 0; i < 10; i++)
{
msleep(50);
if (!get_halfshutter_pressed())
{
return 0;
}
}
}
if (lv && !is_manual_focus())
{
/* try to ignore the AF button, and only take pictures on plain half-shutter */
/* problem: lv_focus_status is not updated right away :( */
bmp_printf(FONT_MED, 0, 37, "Hold on...");
for (int i = 0; i < 10; i++)
{
wait_lv_frames(1);
if (lv_focus_status == 3)
{
while (get_halfshutter_pressed())
{
bmp_printf(FONT_MED, 0, 37, "Focusing...");
msleep(10);
}
redraw();
return 0;
}
}
}
silent_pic_take(1);
}
if (LV_PAUSED && get_halfshutter_pressed())
{
/* long press will trigger a second picture */
/* short press will go back to LiveView */
info_led_on();
for (int i = 0; i < 10; i++)
{
msleep(50);
if (!get_halfshutter_pressed())
{
info_led_off();
ResumeLiveView();
return 0;
}
}
info_led_off();
silent_pic_take(1);
}
return 0;
}
static struct menu_entry silent_menu[] = {
{
.name = "ISO Flash",
.priv = &silent_pic_enabled,
.update = silent_pic_display,
.max = 1,
.depends_on = DEP_LIVEVIEW | DEP_CFN_AF_BACK_BUTTON,
.help = "Take two pics in LiveView without moving the shutter mechanism. \n"
"One at manual chosen ISO, and one at higher selected ISO value",
.submenu_width = 650,
.children = (struct menu_entry[]) {
{
.name = "Recovery ISO",
.priv = &silent_pic_recovery_iso,
.update = isocheck,
.min = -12,
.max = 4,
//.unit = UNIT_ISO,
.choices = CHOICES("100", "125","160","200","250","320","400","500","640","800","1000","1250","1600","2000","2500","3200","4000"),
.help = "ISO for second shot",
//.help2 = "Test",
},
{
.name = "Recovery Shutter",
.priv = &silent_pic_recovery_shutter,
.update = shuttercheck,
.min = -12,
.max = 12,
//.unit = UNIT_ISO,
.choices = CHOICES("60", "80", "90", "100", "125", "160", "180", "200", "250", "320", "350", "400", "500", "640", "750", "800", "1000", "1250", "1500", "1600", "2000", "2500", "3000", "3200", "4000"),
.help = "shutter for second shot",
.help2 = "(Indicated in 1 / value)",
},
MENU_EOL,
}
}
};
static unsigned int silent_init()
{
menu_add("Shoot", silent_menu, COUNT(silent_menu));
/* fixme in core: prop handlers should trigger when initializing, but they do not */
prop_iso = lens_info.raw_iso;
prop_shutter = lens_info.raw_shutter;
//silent_pic_mlv_available = (mlv_generate_guid() != 0ULL);
if (is_camera("500D", "*") || is_camera("550D", "*") || is_camera("600D", "*"))
{
/* see http://www.magiclantern.fm/forum/index.php?topic=12523.msg129874#msg129874 */
long_exposure_fix_enabled = 1;
}
return 0;
}
static unsigned int silent_deinit()
{
return 0;
}
MODULE_INFO_START()
MODULE_INIT(silent_init)
MODULE_DEINIT(silent_deinit)
MODULE_INFO_END()
MODULE_CBRS_START()
MODULE_CBR(CBR_CUSTOM_PICTURE_TAKING, silent_pic_take, 0)
MODULE_CBR(CBR_SHOOT_TASK, silent_pic_polling_cbr, 0)
//MODULE_CBR(CBR_VSYNC, silent_pic_raw_vsync, 0)
//MODULE_CBR(CBR_DISPLAY_FILTER, silent_pic_preview, 0)
MODULE_CBRS_END()
MODULE_CONFIGS_START()
MODULE_CONFIG(silent_pic_recovery_iso)
MODULE_CONFIG(silent_pic_recovery_shutter)
MODULE_CONFIG(silent_pic_enabled)
MODULE_CONFIG(silent_pic_mode)
MODULE_CONFIG(silent_pic_slitscan_mode)
MODULE_CONFIG(silent_pic_file_format)
MODULE_CONFIGS_END()
MODULE_PROPHANDLERS_START()
MODULE_PROPHANDLER(PROP_ISO)
MODULE_PROPHANDLER(PROP_SHUTTER)
MODULE_PROPHANDLERS_END()