void green_screen_step() { /**************************************************** * .. if Canon menu is ACTIVE - return immediately * ****************************************************/ if (!lv) { last_green_screen_state = 0; return; } /******************************** * Masses of auto variables. * ********************************/ // unsigned int Xs,Xe; // X_POSITION of Cropmark_start/_end //~ Xs = g_cropmark_x_start; // First Pix drawn on (and a multiple of 4) //~ Xe = g_cropmark_x_end; // First Pix not drawn on (multiple of 4) // unsigned int Vram_pixels = Xe - Xs; unsigned int vpix, lum1, lum2; // results from previous loop, used for display static int total_luma = 0; static int highest_luma = 0; static int lowest_luma = 256; static int total_pixels = 0; // results for current loop, being updated (will be used at next loop) unsigned int total_luma_tmp = 0; unsigned int highest_luma_tmp = 0; unsigned int lowest_luma_tmp = 256; unsigned int total_pixels_tmp = 0; /**************************************************************** * Set address pointers up to first line in Vram * ****************************************************************/ uint32_t* lv = (uint32_t *) get_yuv422_vram()->vram; if (!lv) return; uint8_t* bm = bmp_vram(); // uint16_t* bm16 = (uint16_t *) bmp_vram(); uint8_t* bm_mirror = (uint8_t *) get_bvram_mirror(); unsigned int average_luma = total_luma / total_pixels; unsigned int high_delta = highest_luma - average_luma; // used to work out colour scale unsigned int low_delta = average_luma - lowest_luma; // colour scale for darker pixels /****************************************************************** * Go through Crop area. Note highest and lowest luma, average * ******************************************************************/ int high_delta_factor = 1024 / high_delta; // replace division with multiplication int low_delta_factor = 1024 / low_delta; for(int y = os.y0 + os.off_169; y < os.y_max - os.off_169; y += 2 ) { uint32_t * const v_row = (uint32_t*)( lv + BM2LV_R(y) ); // 2 pixels uint16_t * const b_row = (uint16_t*)( bm + BM_R(y) ); // 2 pixels uint16_t * const m_row = (uint16_t*)( bm_mirror + BM_R(y) ); // 2 pixels uint8_t* lvp; // that's a moving pointer through lv vram uint16_t* bp; // through bmp vram uint16_t* mp; // through mirror for (int x = os.x0; x < os.x_max; x += 2) { lvp = (uint8_t *) (v_row + BM2LV_X(x)/2); lvp++; bp = b_row + x/2; mp = m_row + x/2; /******************************************** * Get 4 bytes of vram (ie two vram Pixels) * ********************************************/ // vpix = [LSB=pix on left] u y1 v y2 [MSB=pix on right] vpix = lv[BM2LV(x,y)/4]; total_pixels_tmp += 2; lum1 = ( vpix & 0x0000FF00 ) >> 8; // y1 lum2 = ( vpix & 0xFF000000 ) >> 24; // y2 /************************* * Update total luma * *************************/ total_luma_tmp += lum1 + lum2; /************************* * new Maximum ? * *************************/ if (lum1 > highest_luma_tmp) highest_luma_tmp = lum1; if (lum2 > highest_luma_tmp) highest_luma_tmp = lum2; /************************* * new Miniumum ? * *************************/ if (lum1 < lowest_luma_tmp) lowest_luma_tmp = lum1; if (lum2 < lowest_luma_tmp) lowest_luma_tmp = lum2; /********************************************************* * Initialise writeback colour of overlay to 0 for LUM1 * *********************************************************/ unsigned int lum = (lum1 + lum2) / 2; unsigned int col = 0; /************************************** * LUM1 Higher than average luma * **************************************/ if (lum > average_luma) { col = ((lum-average_luma)*12) * high_delta_factor / 1024; if (col > 12) col=12; col = 128 + (col+2) * 8; } else if (lum < average_luma) { /************************************** * LUM1 Lower than average luma * **************************************/ col = ((average_luma-lum)*12) * low_delta_factor / 1024; if (col > 12) col=12; col = 128 - (col+2) * 8; } if (col) col = ((col * 41) >> 8) + 38; unsigned int c = col | (col << 8); #define BP (*bp) #define MP (*mp) #define BN (*(bp + BMPPITCH/2)) #define MN (*(mp + BMPPITCH/2)) if (BP != 0 && BP != MP) { continue; } if (BN != 0 && BN != MN) { continue; } if ((MP & 0x80808080) || (MN & 0x80808080)) continue; MP = BP = c; MN = BN = c; #undef BP #undef MP #undef BN #undef MN } } // end of (y loop) /********************************** * commit statistics for next loop * **********************************/ total_luma = total_luma_tmp; highest_luma = highest_luma_tmp; lowest_luma = lowest_luma_tmp; total_pixels = total_pixels_tmp; /********************************** * Display average, min and max * **********************************/ bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), os.x0 + os.x_ex/2 - font_med.width*7, os.y_max - os.off_169 - 47, "Average = %03d",average_luma); bmp_printf( FONT(FONT_MED,COLOR_CYAN, COLOR_BLACK), os.x0, os.y_max - os.off_169 - 47, "MIN = %03d",lowest_luma); bmp_printf( FONT(FONT_MED,COLOR_YELLOW, COLOR_BLACK), os.x_max - font_med.width*9, os.y_max - os.off_169 - 47, "%03d = MAX",highest_luma); bmp_printf( FONT(FONT_MED,COLOR_WHITE, COLOR_BLACK), os.x0 + os.x_ex/2 - font_med.width*7, os.y_max - os.off_169 - 27, "Accuracy=%03d%%",((255-(highest_luma-lowest_luma))*99 )/255 ); bmp_printf( FONT(FONT_MED,COLOR_CYAN, COLOR_BLACK), os.x0, os.y_max - os.off_169 - 27, "delta %03d", COERCE(average_luma - lowest_luma, 0, 255)); bmp_printf( FONT(FONT_MED, COLOR_YELLOW, COLOR_BLACK), os.x_max - font_med.width*9, os.y_max - os.off_169 - 27, "%03d delta", COERCE(highest_luma - average_luma, 0, 255)); msleep(10); // don't kill the battery :) } /* end of green_screen_step() */
void update_vram_params() { #if CONFIG_DEBUGMSG if (is_menu_active("VRAM")) return; #endif //~ msleep(100); // just to make sure all prop handlers finished after mode change if (!ext_monitor_hdmi) hdmi_code = 0; // 5D doesn't revert it, maybe other cameras too // force a redraw when you connect the external monitor static int prev_hdmi_code = 0; static int prev_EXT_MONITOR_RCA = 0; if (prev_hdmi_code != hdmi_code || prev_EXT_MONITOR_RCA != EXT_MONITOR_RCA) redraw(); prev_hdmi_code = hdmi_code; prev_EXT_MONITOR_RCA = EXT_MONITOR_RCA; // LV crop area (black bars) os.x0 = hdmi_code == 5 ? 75 - 120 : (hdmi_code == 2 ? 40 : EXT_MONITOR_RCA ? (pal ? 40 : 40) : 0); os.y0 = hdmi_code == 5 ? 0 - 30 : (hdmi_code == 2 ? 24 : EXT_MONITOR_RCA ? (pal ? 29 : 25) : 0); os.x_ex = hdmi_code == 5 ? 810 : (hdmi_code == 2 || EXT_MONITOR_RCA) ? 640 : 720; os.y_ex = hdmi_code == 5 ? 540 : (hdmi_code == 2 || EXT_MONITOR_RCA) ? 388 : 480; #if defined(CONFIG_4_3_SCREEN) if (!EXT_MONITOR_CONNECTED) { if (PLAY_MODE || QR_MODE) { os.y0 = 52; // black bar is at the top in play mode, 48 with additional info os.y_ex = 428; // 480 - os.y0; // screen height is 480px in total } else { os.y_ex = 424; // 480 * 8/9; // BMP is 4:3, image is 3:2; } } #else if (PLAY_MODE && hdmi_code == 2) { os.y_ex = 480 - 52; os.y0 = 52; } #endif os.x_max = os.x0 + os.x_ex; os.y_max = os.y0 + os.y_ex; os.off_169 = (os.y_ex - os.y_ex * 3/2 * 9/16) / 2; os.off_1610 = (os.y_ex - os.y_ex * 3/2 * 10/16) / 2; // LV buffer (used for display) // these buffer sizes include any black bars #if defined(CONFIG_5DC) vram_lv.width = 540; vram_lv.height = 426; vram_lv.pitch = vram_lv.width * 2; os.x0 = 0; os.y0 = 26; os.x_ex = 720; os.y_ex = 480-52; os.x_max = os.x0 + os.x_ex; os.y_max = os.y0 + os.y_ex; os.off_169 = 0; os.off_1610 = 0; #elif defined(CONFIG_40D) //~ vram_lv.width = 720; // we only know the HD buffer for now... let's try to pretend it can be used as LV :) //~ vram_lv.height = 480; // we only know the HD buffer for now... let's try to pretend it can be used as LV :) vram_lv.width = 768; // real width is 1024 in yuv411, but ML code assumes yuv422 vram_lv.height = 680; vram_lv.pitch = vram_lv.width * 2; os.x0 = 0; //~ os.y0 = 0; os.y0 = (PLAY_MODE || QR_MODE)? 48 : 0; os.x_ex = 720; //~ os.y_ex = 480; os.y_ex = 480 - os.y0; os.x_max = os.x0 + os.x_ex; os.y_max = os.y0 + os.y_ex; os.off_169 = 0; os.off_1610 = 0; //~ os.off_169 = (os.y_ex - os.y_ex * 4/3 * 9/16) / 2; //~ os.off_1610 = (os.y_ex - os.y_ex * 4/3 * 10/16) / 2; #else #ifdef CONFIG_1100D vram_lv.width = 720; vram_lv.height = 240; #else vram_lv.width = hdmi_code == 5 ? (is_movie_mode() && video_mode_resolution > 0 && video_mode_crop ? 960 : 1920) : EXT_MONITOR_RCA ? 540 : 720; vram_lv.height = hdmi_code == 5 ? (is_movie_mode() && video_mode_fps > 30 ? 540 : 1080) : EXT_MONITOR_RCA ? (pal ? 572 : 480) : 480; #endif vram_lv.pitch = vram_lv.width * 2; #endif #ifdef CONFIG_5DC bm2lv.sx = 1024 * vram_lv.width / 720; bm2lv.sy = 1024 * vram_lv.height / (480-52); bm2lv.tx = 0; bm2lv.ty = -26; #elif CONFIG_40D bm2lv.sx = 1024 * vram_lv.width / 720; bm2lv.sy = 1024 * vram_lv.height / 480; //~ bm2lv.sy = 1024 * vram_lv.height / (480-48); bm2lv.tx = 0; bm2lv.ty = 0; //~ bm2lv.ty = (PLAY_MODE || QR_MODE)? -48 : 0; #else // bmp to lv transformation // LCD: (0,0) -> (0,0) // HDMI: (-120,-30) -> (0,0) and scaling factor is 2 bm2lv.tx = hdmi_code == 5 ? 240 : EXT_MONITOR_RCA ? 4 : 0; bm2lv.ty = hdmi_code == 5 ? (video_mode_resolution>0 ? 30 : 60) : 0; bm2lv.sx = hdmi_code == 5 ? 2048 : EXT_MONITOR_RCA ? 768 : 1024; bm2lv.sy = 1024 * vram_lv.height / (hdmi_code==5 ? 540 : 480); // no black bars at top or bottom #endif //~ lv_ratio_num = hdmi_code == 5 ? 16 : 3; //~ lv_ratio_den = hdmi_code == 5 ? 9 : 2; // HD buffer (used for recording) //~ hd_ratio_num = recording ? (video_mode_resolution < 2 ? 16 : 4) : 3; //~ hd_ratio_den = recording ? (video_mode_resolution < 2 ? 9 : 3) : 2; #if defined(CONFIG_40D) vram_hd.width = vram_lv.width; vram_hd.height = vram_lv.height; vram_hd.pitch = vram_lv.pitch; //~ vram_hd.width = 1024; //~ vram_hd.height = 680; //~ vram_hd.pitch = vram_hd.width * 2; #elif defined(CONFIG_5DC) vram_hd.width = 1872; vram_hd.height = 1664; vram_hd.pitch = vram_lv.pitch; #else vram_hd.pitch = hd_size & 0xFFFF; vram_hd.width = vram_hd.pitch / 2; vram_hd.height = ((hd_size >> 16) & 0xFFFF) #if !defined(CONFIG_DIGIC_V) + 1 #endif ; #endif int off_43 = (os.x_ex - os.x_ex * 8/9) / 2; // gray bars for 16:9 or 4:3 #if defined(CONFIG_600D) int bar_x = is_movie_mode() && video_mode_resolution >= 2 ? off_43 : 0; int bar_y = is_movie_mode() && video_mode_resolution <= 1 ? os.off_169 : 0; #elif defined(CONFIG_1100D) || defined(CONFIG_DIGIC_V) int bar_x = 0; int bar_y = is_movie_mode() && video_mode_resolution == 1 ? os.off_169 : 0; off_43+=0; // bypass warning #elif defined(CONFIG_500D) || defined(CONFIG_7D) //TODO: 650D/6D/EOSM used to have this one enabled too...which one is correct? int bar_x = 0; int bar_y = 0; off_43+=0; // bypass warning #else int bar_x = recording && video_mode_resolution >= 2 ? off_43 : 0; int bar_y = recording && video_mode_resolution <= 1 ? os.off_169 : 0; #endif vram_update_luts(); lv2hd.sx = 1024 * vram_hd.width / BM2LV_DX(os.x_ex - bar_x * 2); lv2hd.sy = 1024 * vram_hd.height / BM2LV_DY(os.y_ex - bar_y * 2); // HD buffer does not contain pillarboxes, LV does // and HD may or may not contain bars // the offset needs to be specified in HD units lv2hd.tx = -LV2HD_DX(BM2LV_X(os.x0 + bar_x)); lv2hd.ty = -LV2HD_DY(BM2LV_Y(os.y0 + bar_y)); //~ #ifndef CONFIG_5DC if (!lv) // HD buffer not active, use LV instead { lv2hd.sx = lv2hd.sy = 1024; lv2hd.tx = lv2hd.ty = 0; vram_hd.pitch = vram_lv.pitch; vram_hd.width = vram_lv.width; vram_hd.height = vram_lv.height; } //~ #endif vram_update_luts(); }
void draw_false_downsampled( void ) { //~ if (vram_width > 720) return; //~ if (!PLAY_MODE) //~ { //~ if (!expsim) return; //~ } // exception: green screen palette is not fixed if (falsecolor_palette == 5) { green_screen_step(); return; } //~ bvram_mirror_init(); uint8_t * const bvram = bmp_vram_real(); if (!bvram) return; uint8_t * const bvram_mirror = get_bvram_mirror(); if (!bvram_mirror) return; uint8_t * const lvram = get_yuv422_vram()->vram; uint8_t* fc = false_colour[falsecolor_palette]; int off = get_y_skip_offset_for_overlays(); for(int y = os.y0 + off; y < os.y_max - off; y += 2 ) { uint32_t * const v_row = (uint32_t*)( lvram + BM2LV_R(y) ); // 2 pixels uint16_t * const b_row = (uint16_t*)( bvram + BM_R(y) ); // 2 pixels uint16_t * const m_row = (uint16_t*)( bvram_mirror + BM_R(y) ); // 2 pixels uint8_t* lvp; // that's a moving pointer through lv vram uint16_t* bp; // through bmp vram uint16_t* mp; // through mirror for (int x = os.x0; x < os.x_max; x += 2) { lvp = (uint8_t *)(v_row + BM2LV_X(x)/2); lvp++; bp = b_row + x/2; mp = m_row + x/2; #define BP (*bp) #define MP (*mp) #define BN (*(bp + BMPPITCH/2)) #define MN (*(mp + BMPPITCH/2)) if (BP != 0 && BP != MP) { little_cleanup(bp, mp); continue; } if (BN != 0 && BN != MN) { little_cleanup(bp + BMPPITCH/2, mp + BMPPITCH/2); continue; } if ((MP & 0x80808080) || (MN & 0x80808080)) continue; int c = fc[*lvp]; c |= (c << 8); MP = BP = c; MN = BN = c; #undef BP #undef MP #undef BN #undef MN } } }