Fandom

Magic Lantern Firmware Wiki

VRAM/550D

< VRAM

328pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

VRAM segments with image data (YUV 422)Edit

Those numbers are not 100% correct. A more elegant method (suggested by AJ) is to find a structure which contains the size of the VRAM buffers, and read the image size directly from there.

0x40D07800 / 4c233800 / 4f11d800Edit

LiveView buffer maybe

  • each buffer updates at 10fps (does not change when NTSC is selected) => 30fps liveview
  • buffer address can be found at 0x246c (updates at 30fps)
  • see the table struct vram_info vram_info[3]; at RAM:0008194C
  • 1440 pitch, 720x480 image size, (3:2)
  • RCA monitor connected: 540x540 with black borders
  • HDMI monitor connected:
    • 1920x1080 (16:9) standby (not recording)
    • 720x486? while recording /* zebra already works in this mode */

0x44000080 / 0x46000080Edit

  • each buffer is updated at 12.5 fps (PAL) or 15fps (NTSC)
  • they are updated alternatively according to AJ's guess => 25 or 30 fps
  • it seems not to change its size when external display is connected
  • in LiveView, idle, PHOTO mode: 2112 pitch, 1056*704 (3:2)
  • when NOT recording:
    • resolution can be found at (0x1300ce, 0x1300d0)
    • full HD: 1056x704
    • 720p: 1024x680 sometimes work, sometimes not
    • 480p non-crop: garbage
    • 480p crop: 640x480
  • when recording:
    • full HD: 3440 pitch, 1720x974 (approx. 16:9)
    • 720p: 2560 pitch, 1280 x 580
    • 480p: 1280 pitch, 640 x 480
  • zoom x5, x10: 2048 pitch, 1024x680 (3:2)

ASM Zedbra: segments in 5D2.

LV-Sizes:Edit

Dimensions can be found at 0x3787c(x) and 0x37880(y) (FW 1.0.9)

Local Display:Edit

Always 720x480

HDMI:Edit

Standby:

  • Disp 1x/2x: 1320x880
  • Disp 3x: 1620x1080

Recording: Always 640x388

A/V-Out (Standby + Recording):Edit

  • PAL: 640x464
  • NTSC: 640x388

BMP overlay (where ML writes stuff on screen)Edit

8-bit palette: see Cropmarks

  • normal: 720x480 (3:2)
  • hdmi monitor: 960*540 (16:9)
  • SD monitor: 720x480 stretched?

How to find segmentsEdit

Some ideas:

  • Scan for contiguous areas of memory which change like mad (AJ's method)
  • Dump some memory twice (while in LiveView or Recording) and plot the difference between them. Use pylab, octave or whatever numerical analysis program you like. Downsample them (e.g. x[0:-1:100] in pylab) if you have huge dumps.
  • Reading from Cxxxxxxx (and maybe from other addresses) may freeze the camera. Be careful.
  • Use FFT to guess the pitch, and then tweak it by hand
def guesspitch(s):
   F,f = fft(s), fftfreq(len(s))    
   for i in range(100): F[i] = 0
   a = argmax(abs(F[:10000]))
   print 1/f[a]
  • Use these functions for reading and splitting YUV data:
def readseg(file, start, size):
   f = open(file)
   f.seek(start)
   d = f.read(size)
   f.close()
   return [ord(x) for x in d]
def img(s,i,off,step,name,signed,pitch):
   nl = len(s)/pitch
   print nl
   s = s[off:]
   a = resize(s,nl*pitch).reshape(nl,pitch)
   a = a[:,0:pitch:step]
   fname = '%03d-%s.png' % (i,name)
   print a.min(), a.max()
   if signed: a = (a.astype(uint8).astype(int32) + 128).astype(uint8)
   else: a = a.astype(uint8)
   b = Image.fromarray(a)
   b.save(fname)
def imgseq(s, pitch, i=0, off=0):
   img(s,i,0+off,1,"full",0,pitch);
   img(s,i,1+off,2,"odd",0,pitch);
   img(s,i,0+off,2,"even",1,pitch);
   img(s,i,0+off,4,"even-even",1,pitch);
   img(s,i,2+off,4,"even-odd",1,pitch);

e.g.

s = readseg("4.BIN", 0x04000080, 1056*704*2)
guesspitch(s)
2112.0
imgseq(s, 2112)

Code: GPL

Code for running on the cameraEdit

static FILE * g_aj_logfile = INVALID_PTR;
unsigned int aj_create_log_file( char * name)
{
   g_aj_logfile = FIO_CreateFile( name );
   if ( g_aj_logfile == INVALID_PTR )
   {
      bmp_printf( FONT_SMALL, 120, 40, "FCreate: Err %s", name );
      return( 0 );  // FAILURE
   }
   return( 1 );  // SUCCESS
}
void aj_close_log_file( void )
{
   if (g_aj_logfile == INVALID_PTR)
      return;
   FIO_CloseFile( g_aj_logfile );
   g_aj_logfile = INVALID_PTR;
}
void dump_seg(uint32_t start, uint32_t size, char* filename)
{
    DEBUG();
    aj_create_log_file(filename);
    FIO_WriteFile( g_aj_logfile, (const void *) start, size );
    aj_close_log_file();
    DEBUG();
}
void dump_big_seg(int k, char* filename)
{
    DEBUG();
    aj_create_log_file(filename);
    
    int i;
    for (i = 0; i < 16; i++)
    {
		DEBUG();
		uint32_t start = (k << 28 | i << 24);
		bmp_printf(FONT_LARGE, 50, 50, "DUMP %x %8x ", i, start);
		FIO_WriteFile( g_aj_logfile, (const void *) start, 0x1000000 );
    }
   
    aj_close_log_file();
    DEBUG();
}
static void dump_vram()
{
	dump_big_seg(1, "B:/1.bin");
	dump_big_seg(4, "B:/4.bin");
}

Step-by-step exampleEdit

Run ipython

  1. Load the code (img.py) from the mailing list
In [1]: run -i img.py
  1. Read the file downsampled by 100, 'cause the dumps are large:
In [2]: a = readsampled("./0.BIN")

And second file:

In [3]: b = readsampled("./1.BIN")

Find a difference...

In [4]: d = array(a) - array(b)

Do this to get a nice plot:

In [5]: d[d != 0] = 1

Notice one of the blocks starting around 1000000:

6. dif

6. diff

In [6]: plot(d); show() 
Out[6]: [<matplotlib.lines.Line2D object at 0x9c93c2c>]

Remember downsampling factor:

In [7]: x = 1000000*100

Read 1MB from there:

In [8]: s = readseg("./0.BIN", x, 1000000)

Guess pitch with FFT:

In [9]: guesspitch(s)
2114.16490486

Starts to look like an image!

10. first guess

10. first guess

In [10]: imgseq(s, 2114)

And... Perfect sync!

11. second guess

11. second guess

In [11]: imgseq(s, 2112)

Image data starts from line 316; from 550d we know buffer is 1056*704

In [12]: s = readseg("./0.BIN", x+316*2112, 2112*704)

Almost there...

13. almost there

13. almost there

In [13]: imgseq(s, 2112)

In [14]: hex(x+316*2112)
Out[14]: '0x6001000'

From 550D, Alex guess it should end in 0080

In [15]: s = readseg("./0.BIN", 0x6000080, 2112*704)

Bingo!

16. bingo!

16. bingo!

In [16]: imgseq(s, 2112)

Final result: 0x46000080 (with the caching bit from 550D).

References:

Also on Fandom

Random Wiki