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() */
示例#2
0
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();
}
示例#3
0
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
        }
    }
}