Commit 89ab0dac authored by alex@thinkpad's avatar alex@thinkpad
Browse files

Merged in raw_capture_info (pull request #827)

--HG--
branch : unified
......@@ -148,7 +148,6 @@ static int res_x = 0;
static int res_y = 0;
static int max_res_x = 0;
static int max_res_y = 0;
static int sensor_res_x = 0;
static float squeeze_factor = 0;
static int frame_size = 0;
static int frame_size_real = 0;
......@@ -214,6 +213,7 @@ static uint32_t edmac_active = 0;
static mlv_file_hdr_t file_hdr;
static mlv_rawi_hdr_t rawi_hdr;
static mlv_rawc_hdr_t rawc_hdr;
static mlv_idnt_hdr_t idnt_hdr;
static mlv_expo_hdr_t expo_hdr;
static mlv_lens_hdr_t lens_hdr;
......@@ -484,32 +484,13 @@ static void refresh_raw_settings(int force)
}
}
PROP_HANDLER( PROP_LV_AFFRAME ) {
ASSERT(len <= 128);
if(!lv) return;
sensor_res_x = ((int32_t*)buf)[0];
}
static int32_t calc_crop_factor()
static int calc_crop_factor()
{
int sensor_res_x = raw_capture_info.sensor_res_x;
int camera_crop = raw_capture_info.sensor_crop;
int sampling_x = raw_capture_info.binning_x + raw_capture_info.skipping_x;
int32_t camera_crop = 162;
int32_t sampling_x = 3;
if (cam_5d2 || cam_5d3 || cam_6d) camera_crop = 100;
//if (cam_500d || cam_50d) sensor_res_x = 4752;
//if (cam_eos_m || cam_550d || cam_600d || cam_650d || cam_700d || cam_60d || cam_7d) sensor_res_x = 5184;
//if (cam_6d) sensor_res_x = 5472;
//if (cam_5d2) sensor_res_x = 5616;
//if (cam_5d3) sensor_res_x = 5760;
if (video_mode_crop || (lv_dispsize > 1)) sampling_x = 1;
if (!sensor_res_x) return 0;
if (res_x == 0) return 0;
return camera_crop * (sensor_res_x / sampling_x) / res_x;
}
......@@ -530,7 +511,7 @@ static MENU_UPDATE_FUNC(raw_main_update)
else
{
MENU_SET_VALUE("ON, %dx%d", res_x, res_y);
int32_t crop_factor = calc_crop_factor();
int crop_factor = calc_crop_factor();
if (crop_factor) MENU_SET_RINFO("%s%d.%02dx", FMT_FIXEDPOINT2( crop_factor ));
}
......@@ -1604,7 +1585,24 @@ static void init_mlv_chunk_headers(struct raw_info * raw_info)
rawi_hdr.xRes = res_x;
rawi_hdr.yRes = res_y;
rawi_hdr.raw_info = *raw_info;
memset(&rawc_hdr, 0, sizeof(mlv_rawc_hdr_t));
mlv_set_type((mlv_hdr_t *)&rawc_hdr, "RAWC");
mlv_set_timestamp((mlv_hdr_t *)&rawc_hdr, mlv_start_timestamp);
rawc_hdr.blockSize = sizeof(mlv_rawc_hdr_t);
/* copy all fields from raw_capture_info */
rawc_hdr.sensor_res_x = raw_capture_info.sensor_res_x;
rawc_hdr.sensor_res_y = raw_capture_info.sensor_res_y;
rawc_hdr.sensor_crop = raw_capture_info.sensor_crop;
rawc_hdr.reserved = raw_capture_info.reserved;
rawc_hdr.binning_x = raw_capture_info.binning_x;
rawc_hdr.skipping_x = raw_capture_info.skipping_x;
rawc_hdr.binning_y = raw_capture_info.binning_y;
rawc_hdr.skipping_y = raw_capture_info.skipping_y;
rawc_hdr.offset_x = raw_capture_info.offset_x;
rawc_hdr.offset_y = raw_capture_info.offset_y;
mlv_fill_idnt(&idnt_hdr, mlv_start_timestamp);
mlv_fill_expo(&expo_hdr, mlv_start_timestamp);
mlv_fill_lens(&lens_hdr, mlv_start_timestamp);
......@@ -1683,6 +1681,7 @@ static int write_mlv_chunk_headers(FILE* f)
{
if (FIO_WriteFile(f, &file_hdr, file_hdr.blockSize) != (int)file_hdr.blockSize) return 0;
if (FIO_WriteFile(f, &rawi_hdr, rawi_hdr.blockSize) != (int)rawi_hdr.blockSize) return 0;
if (FIO_WriteFile(f, &rawc_hdr, rawc_hdr.blockSize) != (int)rawc_hdr.blockSize) return 0;
if (FIO_WriteFile(f, &idnt_hdr, idnt_hdr.blockSize) != (int)idnt_hdr.blockSize) return 0;
if (FIO_WriteFile(f, &expo_hdr, expo_hdr.blockSize) != (int)expo_hdr.blockSize) return 0;
if (FIO_WriteFile(f, &lens_hdr, lens_hdr.blockSize) != (int)lens_hdr.blockSize) return 0;
......
......@@ -91,6 +91,40 @@ typedef struct {
struct raw_info raw_info; /* the raw_info structure delivered by raw.c of ML Core */
} mlv_rawi_hdr_t;
typedef struct {
uint8_t blockType[4]; /* RAWC - raw image capture information */
uint32_t blockSize; /* sizeof(mlv_rawc_hdr_t) */
uint64_t timestamp; /* hardware counter timestamp */
/* see struct raw_capture_info from raw.h */
/* sensor attributes: resolution, crop factor */
uint16_t sensor_res_x; /* sensor resolution */
uint16_t sensor_res_y; /* 2-3 GPixel cameras anytime soon? (to overflow this) */
uint16_t sensor_crop; /* sensor crop factor x100 */
uint16_t reserved; /* reserved for future use */
/* video mode attributes */
/* (how the sensor is configured for image capture) */
/* subsampling factor: (binning_x+skipping_x) x (binning_y+skipping_y) */
uint8_t binning_x; /* 3 (1080p and 720p); 1 (crop, zoom) */
uint8_t skipping_x; /* so far, 0 everywhere */
uint8_t binning_y; /* 1 (most cameras in 1080/720p; also all crop modes); 3 (5D3 1080p); 5 (5D3 720p) */
uint8_t skipping_y; /* 2 (most cameras in 1080p); 4 (most cameras in 720p); 0 (5D3) */
int16_t offset_x; /* crop offset (top-left active pixel) - optional (SHRT_MIN if unknown) */
int16_t offset_y; /* relative to top-left active pixel from a full-res image (FRSP or CR2) */
/* The captured *active* area (raw_info.active_area) will be mapped
* on a full-res image (which does not use subsampling) as follows:
* active_width = raw_info.active_area.x2 - raw_info.active_area.x1
* active_height = raw_info.active_area.y2 - raw_info.active_area.y1
* .x1 (left) : offset_x + full_res.active_area.x1
* .y1 (top) : offset_y + full_res.active_area.y1
* .x2 (right) : offset_x + active_width * (binning_x+skipping_x) + full_res.active_area.x1
* .y2 (bottom): offset_y + active_height * (binning_y+skipping_y) + full_res.active_area.y1
*/
} mlv_rawc_hdr_t;
typedef struct {
uint8_t blockType[4]; /* when audioClass is WAV, this block contains format details compatible to RIFF */
uint32_t blockSize; /* total frame size */
......
......@@ -1030,6 +1030,69 @@ void show_usage(char *executable)
print_msg(MSG_INFO, "\n");
}
void print_sampling_info(int bin, int skip, char * what)
{
if (bin + skip == 1) {
print_msg(MSG_INFO, "read every %s", what);
} else if (skip == 0) {
print_msg(MSG_INFO, "bin %d %s%s", bin, what, bin == 1 ? "" : "s");
} else {
print_msg(MSG_INFO, "%s %d %s%s", bin == 1 ? "read" : "bin", bin, what, bin == 1 ? "" : "s");
if (skip) {
print_msg(MSG_INFO, ", skip %d", skip);
}
}
}
void print_capture_info(mlv_rawc_hdr_t * rawc)
{
print_msg(
MSG_INFO, " raw_capture_info:\n"
);
print_msg(
MSG_INFO, " sensor res %dx%d\n",
rawc->sensor_res_x,
rawc->sensor_res_y
);
print_msg(
MSG_INFO, " sensor crop %d.%02d (%s)\n",
rawc->sensor_crop / 100,
rawc->sensor_crop % 100,
rawc->sensor_crop == 100 ? "Full frame" :
rawc->sensor_crop == 162 ? "APS-C" : "35mm equiv"
);
int sampling_x = rawc->binning_x + rawc->skipping_x;
int sampling_y = rawc->binning_y + rawc->skipping_y;
print_msg(
MSG_INFO, " sampling %dx%d (",
sampling_y, sampling_x
);
print_sampling_info(
rawc->binning_y,
rawc->skipping_y,
"line"
);
print_msg(MSG_INFO, ", ");
print_sampling_info(
rawc->binning_x,
rawc->skipping_x,
"column"
);
print_msg(MSG_INFO, ")\n");
if (rawc->offset_x != -32768 &&
rawc->offset_y != -32768)
{
print_msg(
MSG_INFO, " offset %d,%d\n",
rawc->offset_x,
rawc->offset_y
);
}
}
int main (int argc, char *argv[])
{
char *input_filename = NULL;
......@@ -3278,6 +3341,27 @@ read_headers:
}
}
}
else if(!memcmp(buf.blockType, "RAWC", 4))
{
mlv_rawc_hdr_t block_hdr;
uint32_t hdr_size = MIN(sizeof(mlv_rawc_hdr_t), buf.blockSize);
if(fread(&block_hdr, hdr_size, 1, in_file) != 1)
{
print_msg(MSG_ERROR, "File ends in the middle of a block\n");
goto abort;
}
/* skip remaining data, if there is any */
file_set_pos(in_file, position + block_hdr.blockSize, SEEK_SET);
lua_handle_hdr(lua_state, buf.blockType, &block_hdr, sizeof(block_hdr));
if(verbose)
{
print_capture_info(&block_hdr);
}
}
else if(!memcmp(buf.blockType, "WAVI", 4))
{
mlv_wavi_hdr_t block_hdr;
......
......@@ -170,7 +170,6 @@ static int32_t res_x = 0;
static int32_t res_y = 0;
static int32_t max_res_x = 0;
static int32_t max_res_y = 0;
static int32_t sensor_res_x = 0;
static float squeeze_factor = 0;
static int32_t frame_size = 0;
static int32_t skip_x = 0;
......@@ -747,17 +746,11 @@ static void refresh_raw_settings(int32_t force)
static int32_t calc_crop_factor()
{
int32_t camera_crop = 162;
int32_t sampling_x = 3;
if (cam_5d2 || cam_5d3 || cam_6d) camera_crop = 100;
if (video_mode_crop || (lv_dispsize > 1)) sampling_x = 1;
get_afframe_sensor_res(&sensor_res_x, NULL);
if (!sensor_res_x) return 0;
if (!res_x) return 0;
int sensor_res_x = raw_capture_info.sensor_res_x;
int camera_crop = raw_capture_info.sensor_crop;
int sampling_x = raw_capture_info.binning_x + raw_capture_info.skipping_x;
if (res_x == 0) return 0;
return camera_crop * (sensor_res_x / sampling_x) / res_x;
}
......@@ -2430,6 +2423,29 @@ static int32_t mlv_write_rawi(FILE* f, struct raw_info raw_info)
return mlv_write_hdr(f, (mlv_hdr_t *)&rawi);
}
static int32_t mlv_write_rawc(FILE* f)
{
mlv_rawc_hdr_t rawc;
mlv_set_type((mlv_hdr_t *)&rawc, "RAWC");
mlv_set_timestamp((mlv_hdr_t *)&rawc, mlv_start_timestamp);
rawc.blockSize = sizeof(mlv_rawc_hdr_t);
/* copy all fields from raw_capture_info */
rawc.sensor_res_x = raw_capture_info.sensor_res_x;
rawc.sensor_res_y = raw_capture_info.sensor_res_y;
rawc.sensor_crop = raw_capture_info.sensor_crop;
rawc.reserved = raw_capture_info.reserved;
rawc.binning_x = raw_capture_info.binning_x;
rawc.skipping_x = raw_capture_info.skipping_x;
rawc.binning_y = raw_capture_info.binning_y;
rawc.skipping_y = raw_capture_info.skipping_y;
rawc.offset_x = raw_capture_info.offset_x;
rawc.offset_y = raw_capture_info.offset_y;
return mlv_write_hdr(f, (mlv_hdr_t *)&rawc);
}
static uint32_t find_largest_buffer(uint32_t start_group, write_job_t *write_job, uint32_t max_size)
{
write_job_t job;
......@@ -2607,6 +2623,7 @@ static void raw_prepare_chunk(FILE *f, mlv_file_hdr_t *hdr)
if(hdr->fileNum == 0)
{
mlv_write_rawi(f, raw_info);
mlv_write_rawc(f);
mlv_write_info(f);
mlv_rtci_hdr_t rtci_hdr;
......
......@@ -56,6 +56,8 @@
#define CBR_INTERVALOMETER 12 /* called after a picture is taken with the intervalometer */
#define CBR_CONFIG_SAVE 13 /* called when ML configs are being saved */
#define CBR_RAW_INFO_UPDATE 14 /* called after raw_info is updated successfully */
/* return values from CBRs */
#define CBR_RET_CONTINUE 0 /* keep calling other CBRs of the same type */
#define CBR_RET_STOP 1 /* stop calling other CBRs */
......
......@@ -309,6 +309,26 @@ struct raw_info raw_info = {
.dynamic_range = 1100, // not correct; use numbers from DxO instead
};
struct raw_capture_info raw_capture_info = {
#ifdef CONFIG_FULLFRAME
.sensor_crop = 100, /* 1.0 */
#else
.sensor_crop = 162, /* 1.62x (APS-C) */
#endif
.binning_x = 1,
.binning_y = 1,
.skipping_x = 0,
.skipping_y = 0,
.offset_x = SHRT_MIN,
.offset_y = SHRT_MIN,
};
PROP_HANDLER(PROP_LV_AFFRAME)
{
raw_capture_info.sensor_res_x = buf[0];
raw_capture_info.sensor_res_y = buf[1];
}
/**
* Dynamic range, from DxO
* e.g. http://www.dxomark.com/index.php/Cameras/Camera-Sensor-Database/Canon/EOS-5D-Mark-III
......@@ -626,7 +646,7 @@ static int raw_update_params_work()
dbg_printf("Photo raw size error\n");
return 0;
}
/**
* The RAW file has unused areas, called "optical black" (OB); we need to skip them.
*
......@@ -716,6 +736,35 @@ static int raw_update_params_work()
dirty = 1;
}
/* photo mode and crop/zoom modes use 1:1 readout */
/* LiveView uses 3x3 column binning / line skipping on most models */
/* and 3x5 in 720p */
if (!lv || zoom || video_mode_crop)
{
raw_capture_info.binning_x = raw_capture_info.binning_y = 1;
raw_capture_info.skipping_x = raw_capture_info.skipping_y = 0;
raw_capture_info.offset_x = raw_capture_info.offset_y = lv ? SHRT_MIN : 0;
}
else
{
raw_capture_info.binning_x = 3; raw_capture_info.skipping_x = 0;
#ifdef CONFIG_5D3
raw_capture_info.skipping_y = 0; raw_capture_info.binning_y = mv720 ? 5 : 3;
#elif CONFIG_EOSM
raw_capture_info.binning_y = 1; raw_capture_info.skipping_y = (mv720 || !RECORDING_H264) ? 4 : 2;
#else
raw_capture_info.binning_y = 1; raw_capture_info.skipping_y = mv720 ? 4 : 2;
#endif
raw_capture_info.offset_x = raw_capture_info.offset_y = SHRT_MIN;
}
dbg_printf(
"Subsampling mode: %dB%dSx%dB%dS (%dx%d %d.%02d)\n",
raw_capture_info.binning_x, raw_capture_info.skipping_x,
raw_capture_info.binning_y, raw_capture_info.skipping_y,
raw_capture_info.sensor_res_x, raw_capture_info.sensor_res_y,
raw_capture_info.sensor_crop / 100, raw_capture_info.sensor_crop % 100
);
#ifdef CONFIG_RAW_LIVEVIEW
if (lv)
......@@ -897,6 +946,7 @@ static int raw_update_params_once()
int ans = 0;
take_semaphore(raw_sem, 0);
ans = raw_update_params_work();
if (ans) module_exec_cbr(CBR_RAW_INFO_UPDATE);
give_semaphore(raw_sem);
return ans;
}
......@@ -1808,7 +1858,10 @@ static void raw_lv_update()
for (int i = 0; i < 5; i++)
{
if (raw_update_params_work())
{
module_exec_cbr(CBR_RAW_INFO_UPDATE);
break;
}
wait_lv_frames(1);
}
}
......
......@@ -204,6 +204,37 @@ struct raw_info {
extern struct raw_info raw_info;
/* image capture parameters */
struct raw_capture_info {
/* sensor attributes: resolution, crop factor */
uint16_t sensor_res_x; /* sensor resolution */
uint16_t sensor_res_y; /* 2-3 GPixel cameras anytime soon? (to overflow this) */
uint16_t sensor_crop; /* sensor crop factor x100 */
uint16_t reserved; /* reserved for future use */
/* video mode attributes */
/* (how the sensor is configured for image capture) */
/* subsampling factor: (binning_x+skipping_x) x (binning_y+skipping_y) */
uint8_t binning_x; /* 3 (1080p and 720p); 1 (crop, zoom) */
uint8_t skipping_x; /* so far, 0 everywhere */
uint8_t binning_y; /* 1 (most cameras in 1080/720p; also all crop modes); 3 (5D3 1080p); 5 (5D3 720p) */
uint8_t skipping_y; /* 2 (most cameras in 1080p); 4 (most cameras in 720p); 0 (5D3) */
int16_t offset_x; /* crop offset (top-left active pixel) - optional (SHRT_MIN if unknown) */
int16_t offset_y; /* relative to top-left active pixel from a full-res image (FRSP or CR2) */
/* The captured *active* area (raw_info.active_area) will be mapped
* on a full-res image (which does not use subsampling) as follows:
* active_width = raw_info.active_area.x2 - raw_info.active_area.x1
* active_height = raw_info.active_area.y2 - raw_info.active_area.y1
* .x1 (left) : offset_x + full_res.active_area.x1
* .y1 (top) : offset_y + full_res.active_area.y1
* .x2 (right) : offset_x + active_width * (binning_x+skipping_x) + full_res.active_area.x1
* .y2 (bottom): offset_y + active_height * (binning_y+skipping_y) + full_res.active_area.y1
*/
};
extern struct raw_capture_info raw_capture_info;
/* save a DNG file; all parameters are taken from raw_info */
int save_dng(char* filename, struct raw_info * raw_info);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment