Canon 7D Mark II

Started by Pelican, November 02, 2014, 09:55:18 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

names_are_hard

Quote from: heder on January 23, 2024, 03:15:59 PM
Dont mind vsync, it's not critical for now.
Good to know.

Quote
1. Does "lv_save_raw" exist as a string in ghidra ?. It might also have changed name, like on the 7D2 I cant find any more "fdump" its now called "fdumpall" or "oldfdumpall", search for "save_raw" and investigate those places.

Yes, the same function exists, I've called it.  I've had it marked in my 200D project for over a year.  It doesn't do what you describe (on this cam).  As in my previous post: running call("lv_save_raw") does not trigger any new usage of channels or devices that I can see, and there is no bayer data saved to in-use edmac buffers.

That's why I'm asking questions about how you see edmac usage change when *you* call it.  So I can try to find the buffer *without* looking for the bayer data directly, since that doesn't happen here (or, perhaps the buffer is reused quickly and my logging isn't fast enough, etc).

heder

Quote from: names_are_hard on January 23, 2024, 03:33:23 PM
That's why I'm asking questions about how you see edmac usage change when *you* call it.  So I can try to find the buffer *without* looking for the bayer data directly, since that doesn't happen here (or, perhaps the buffer is reused quickly and my logging isn't fast enough, etc).

The way I found the RAW EDMAC channel on 40D and 7D2  was starting LiveView and by reading the uint32_t value from all MEM(EDMAC_CHANNEL + 0x10) before and after call("lv_save_raw"). The channel that changed from 0 to something was the RAW EDMAC channel.
... some text here ..

names_are_hard

Thanks, I haven't monitored that field changing, worth a try.  I'm very likely going to refactor the code to stop using those ugly consts for edmac MMIO.  The struct looks like this:


413 struct edmac_mmio
414 {
415     uint32_t dma_state;
416     uint32_t dma_flags;
417     uint32_t ram_dst_offset;
418     uint32_t yn_xn;
419     uint32_t yb_xb;
420     uint32_t ya_xa;
421     uint32_t off1b;
422     uint32_t off2b;
423     uint32_t off1a;
424     uint32_t off2a;
425     uint32_t off3;
426     uint32_t unk_01;
427     uint32_t irq_reason;
428     uint32_t irq_related;
429     uint32_t unk_02;
430     uint32_t unk_03;
431     uint32_t fencing_related_maybe;
432     uint32_t unk_04[0x2f]; // padding?  Probably some but not all.
433 };
434 SIZE_CHECK_STRUCT(edmac_mmio, 0x100);


You can then cast the MMIO "channel" addresses.  Much nicer checking mmio->yb_xb.

I may have found the buffer used by lv_save_raw via static analysis (there's a pointer global, get's populated in LV).  I've dumped image data from it and it's clearly real, but I don't understand the format.  It might be packed 14-bit bayer, but if so I'm missing some detail required to decode it to a sane image, colours are all wrong.

Could you share a dump of that mem region, for a known good capture?

kitor

On R (D8) this evproc sequence saves the raw buffer on card. Format unknown, selected by lv_set_raw_wp.  There are 26 formats (?) to choose from, coming from SantaPath or SAP Path. edmac_info source suggests biggest size is 2016x921 (?) which when decoded as YUV produces completely broken image with somehow visible outline of original context.


lv_set_mm 1
lv_set_raw_wp 0
lv_save_raw 1
lv_raw_dump


Reference frame


Source file (buffer dump): https://kitor.pl/eos/r_edmac/test1.raw

Source decoded as YUV
Too many Canon cameras.
If you have a dead R, RP, 250D mainboard (e.g. after camera repair) and want to donate for experiments, I'll cover shipping costs.

names_are_hard

Fixed.  I can scrape 14-bit packed raw data.  I had some bug in the python I was using to unpack to 16-bit.  Still not sure what it is, rewrote it in C.

https://i.imgur.com/LklrBm3.png

I'll now try and get 7D2 and 200D working with modern mlv_lite.

theBilalFakhouri


heder

I re-encoded the raw 14 bits stream into 16 bits unsigned stream, saved it, and loaded it into gimp. Gimp can load RAW images if they're
encoded correctly (Grey little endian 16 bits).


#include <stdio.h>
#include <stdlib.h>
#include "string.h"

int main(int argc, char *argv[])
{
    FILE *f;
    unsigned int length;
    unsigned short *u16;
    unsigned short *bayer;

    f = fopen(argv[1],"r");
    if (f==NULL || argc != 3)
    {
      printf("No such file. Input argument is : filename length\n");
      return -1;
    }

    sscanf(argv[2],"%d",&length);

    u16 = malloc(2*length);
    bayer = malloc(length);

    memset(u16,0x0,2*length);
    memset(bayer,0x0,length);

    fread(bayer,1,length,f);

    int k=1,i=0;
   
    for (i=0;i<length;i+=8)
    {   

      u16[i+0] =                               (bayer[k+0] & 0xFFFC) >> 2;
      u16[i+1] = (bayer[k+0] & 0x0003) << 12 | (bayer[k+1] & 0xFFF0) >> 4;
      u16[i+2] = (bayer[k+1] & 0x000F) << 10 | (bayer[k+2] & 0xFF00) >> 6;
      u16[i+3] = (bayer[k+2] & 0x003F) << 8  | (bayer[k+3] & 0xFC00) >> 8;
      u16[i+4] = (bayer[k+3] & 0x00FF) << 6  | (bayer[k+4] & 0xF000) >> 10;
      u16[i+5] = (bayer[k+4] & 0x03FF) << 4  | (bayer[k+5] & 0xC000) >> 12;
      u16[i+6] = (bayer[k+5] & 0x0FFF) << 2  | (bayer[k+6] & 0x3000) >> 14;
      u16[i+7] = (bayer[k+6] & 0x3FFF) << 0;
      k+= 7;     
    }

    FILE *fout = fopen("output.data","w+");
    fwrite(u16,1,i*2,fout);
    fclose(fout);   

    return 0;
}



I used this on a RAW dump from sensor https://drive.google.com/file/d/1mhUpk9ju65U3oGHgyxbSqMW4hUfXCdx4/view?usp=sharing and got



... some text here ..

kitor

Yup, @names_are_hard wrote unpacking again in C... and it works, both for 200D and R.
R turned out to be 2304x922 (including black borders), 2257x900 when cut. So many bad pixels ::)
Too many Canon cameras.
If you have a dead R, RP, 250D mainboard (e.g. after camera repair) and want to donate for experiments, I'll cover shipping costs.

Walter Schulz

There is a slight glitch in upper part. All pixels shifted 1-2 pixels sideways. Normal?

EDIT: 1 glitch > 2 pixel. Below at least 2 other glitches.

names_are_hard

Probably not important - I suspect heder did what I did for this first test: handheld it and dumped data direct to disk with FIO_WriteFile().  Mine all look the same, it's not fast enough to avoid tearing.  Heder's real code uses a faster method, I assume no problem there.

names_are_hard

Cleanly adapting modern cams to the existing code will require significant changes.

An example from edmac.c (there are many examples I could use!):

119 uint32_t edmac_get_base(uint32_t channel)
120 {
121     if (channel >= NUM_EDMAC_CHANNELS)
122     {
123         return -1;
124     }
125
126     uint32_t bases[] = { 0xC0F04000, 0xC0F26000, 0xC0F30000 };
127     uint32_t edmac_block = channel >> 4;
128     uint32_t edmac_num = channel & 0x0F;
129
130     return bases[edmac_block] + (edmac_num << 8);
131 }
132
133 static uint32_t edmac_get_block(uint32_t reg)
134 {
135     switch (reg & 0xFFFFF000)
136     {
137         case 0xC0F04000: return 0;
138         case 0xC0F26000: return 1;
139         case 0xC0F30000: return 2;
140         default: return 0xFFFFFFFF;
141     }
142 }


This hardcodes the same magic addresses twice, in different places.  The addresses don't hold for new cams.  And new cams use 4 regions, not 3.  Edmac code doesn't use structs, but uses raw offsets to base addresses, with no explanations.  It's really ugly code, with no docs or explanations in the code (some on the wiki).

Changing the old code needs to be done carefully, or it will fail on old cams.  Changing the old code must be done, or it can't work on new cams.

I could hack in a quick version for 200d (or 7d2), but I'd greatly prefer taking the time to fix things so any cam can use the same code, probably with some new platform/XXD constants defined.

kitor

And btw, DIGIC 8 EDMAC MMIO registers doesn't match old ones at all (offsets, number of registers used for various stuff). That was expected after we found it uses extra dimension... but even if we understand the new controller, integrating that without structures would be a total mess.

Btw, @names_hare_hard I think we should probably pull this recent discussion into a separate thread.
Too many Canon cameras.
If you have a dead R, RP, 250D mainboard (e.g. after camera repair) and want to donate for experiments, I'll cover shipping costs.

names_are_hard

_engio_write() is probably at 13ea0.  Untested.  Testing it is potentially risky, I assume you already know that, heder :)

heder

Yes, and it's to pretty important for FPS engio override.  It's lucky for us that ICU/Marius seems to set the FPS registers via this function and even more luck, it's located in RAM so we even can hijack it (if needed). We'll properly need to log the FPS registers values (0xD0006008. 0xD0006014) for the different canon fps to find the pixel clock needed in fps-engio.c, either via the canon log (it call DryOsDebugMessage) or via hijacking.
... some text here ..

heder

Brief update.

Sorry too little time for discord  :(

I'm cleaning the old hack repo and making a new clean one. Updating to the newest mlv_lite and creating a version with direct buffering so all can use this if they need it. Also inforcing that both ICU(Marius) and Omar cores uses shamem, should make fps override easy to use. Next milestone will be around 7th of Marts. The biggest issue atm is missing edmac api, as all the functions are located on Omar, but I know for a fact that ICU(Marius) does use edmac channels (firmware string "mossy") so it's possible to use edmac from ICU(Marius). Also I will look into card spamming on mlv_lite as this could enable 3k@14bit recording ~ 195 MiB/s ..

* clean repo
* fix start/stop record activation issues
* Enforce Marius to use shamem
* Enable fps override
* Investigate card spanning on mlv_rec
* Investigate how allocate more memory
... some text here ..


theBilalFakhouri

Quote from: heder on February 02, 2024, 09:53:35 AM
Also I will look into card spamming on mlv_lite as this could enable 3k@14bit recording ~ 195 MiB/s ..

This commit adds card spanning support for mlv_lite might help you too.

names_are_hard

Quote from: heder on February 02, 2024, 09:53:35 AM
I'm cleaning the old hack repo and making a new clean one. Updating to the newest mlv_lite and creating a version with direct buffering so all can use this if they need it. Also inforcing that both ICU(Marius) and Omar cores uses shamem, should make fps override easy to use. Next milestone will be around 7th of Marts. The biggest issue atm is missing edmac api, as all the functions are located on Omar, but I know for a fact that ICU(Marius) does use edmac channels (firmware string "mossy") so it's possible to use edmac from ICU(Marius). Also I will look into card spamming on mlv_lite as this could enable 3k@14bit recording ~ 195 MiB/s ..

Progress sounds good!

I have 200D working with modern mlv_lite, with normal buffering.  So you may want to do that part last, as I am still intending to port your 7D2 code in a similar way.  When I have 200D working cleanly with nice code, porting 7D2 should be easy enough.  Unfortunately, I still have some last problem to work out; the video data captured from 200D is scrambled when mlv_lite is used.  I think perhaps some bad offset or width calculation - if I manually capture the buffer the data is correct.  There are lots of hard-coded constants, it's been quite tedious to debug things :(

I'm not forcing you to use discord but it would make things easier to coordinate :P  You don't have to install anything, it works from a browser.

heder

Quote from: Danne on February 02, 2024, 11:42:34 PM
You can check card spanning implementation on mlv_lite here. @Ilia3101 effort.
https://bitbucket.org/Dannephoto/magic-lantern_dannephoto_git/src/master/
https://bitbucket.org/Dannephoto/magic-lantern_dannephoto_git/src/master/modules/mlv_lite/mlv_lite.c

Quote from: theBilalFakhouri on February 03, 2024, 03:31:09 AM
This commit adds card spanning support for mlv_lite might help you too.

Thats awesome!, that feature is absolutely fantastic, one less problem to deal with.

Quote from: names_are_hard on February 03, 2024, 03:00:31 PM
Unfortunately, I still have some last problem to work out; the video data captured from 200D is scrambled when mlv_lite is used.  I think perhaps some bad offset or width calculation - if I manually capture the buffer the data is correct.  There are lots of hard-coded constants, it's been quite tedious to debug things :(

One scenario is that the timing is wrong, i.e. the module_cbr syncronization call that ends up in mlv_lite:process_frame() needs to be correct, otherwise the frame will be "data noise". on 7D2 I had to guess and hijack different function before I got lucky.
... some text here ..

names_are_hard

It's a code problem in mlv, not sure where yet.  It's producing an output file that claims to be 1920 * 1080, but contains data that is 2096 * 1164 (the correct size of the image).  mlvdump, and mlvapp, seem to be trusting the 1920 * 1080 fields, but filling the display from the 2096 wide data, so everything is the wrong colours and skewed.  I can see both values inside the file:


https://i.imgur.com/XR89GXZ.png

Time to learn mlv format and fix the code I guess.

heder

Quote from: names_are_hard on February 04, 2024, 03:29:57 PM
It's a code problem in mlv, not sure where yet.  It's producing an output file that claims to be 1920 * 1080, but contains data that is 2096 * 1164 (the correct size of the image).  mlvdump, and mlvapp, seem to be trusting the 1920 * 1080 fields, but filling the display from the 2096 wide data, so everything is the wrong colours and skewed.  I can see both values inside the file:


https://i.imgur.com/XR89GXZ.png

Time to learn mlv format and fix the code I guess.

Did you set the correct black borders values in raw.c ?


        /**
         * The RAW file has unused areas, usually black; we need to skip them.
         *
         * To find the skip values, start with 0,
         * load the RAW in your favorite photo editor (e.g. ufraw+gimp),
         * then find the usable area, read the coords and plug the skip values here.
         *
         * Try to use even offsets only, otherwise the colors will be screwed up.
         */
        #ifdef CONFIG_5D2
        skip_top        = zoom ?   52 : 18;
        skip_left       = 160;
        #endif

        #ifdef CONFIG_5D3
        skip_top        = zoom ?   60 : mv720 ?  20 :   28;
        skip_left       = 146;
        skip_right      = 2;
        #endif

        #ifdef CONFIG_6D
        /* same skip offsets in 1080p and 720p; top/left bar is the same in x5 zoom as well */
        skip_top        = 28;
        skip_left       = 80;
        skip_right      = zoom ? 0  : 10;
        #endif

        #ifdef CONFIG_500D
        // FIXME: are these values correct for 1080p or 720p? (which of them?)
        skip_top    = 24;
        skip_left   = zoom ? 64 : 74;
        #endif

        #if defined(CONFIG_550D) || defined(CONFIG_600D)
        // FIXME: are these values correct for 720p and crop modes?
        skip_top    = 26;
        skip_left   = zoom ? 0 : 152;
        skip_right  = zoom ? 0 : 2;
        #endif

        #ifdef CONFIG_1100D
        skip_top = 16;
        skip_left = zoom ? 72 : 68;
        #endif

        #ifdef CONFIG_60D
        skip_top    = 26;
        skip_left   = zoom ? 0 : mv640crop ? 150 : 152;
        skip_right  = zoom ? 0 : mv640crop ? 0 : 2;
        #endif

        #ifdef CONFIG_50D
        skip_top    =  26;
        skip_left   =  zoom ? 64: 74;
        skip_right  = 0;
        #endif

        #if defined(CONFIG_EOSM) || defined(CONFIG_700D) || defined(CONFIG_650D) || defined(CONFIG_100D)
        skip_top    = 28;
        skip_left   = 72;
        skip_right  = 0;
        #ifdef CONFIG_100D
        /* 720p: H=727-1, last valid line at y=723, 2 white lines at bottom */
        /* VRAM dumps, please: http://www.magiclantern.fm/forum/index.php?topic=12375.0 */
        skip_bottom = zoom ? 0 : mv1080crop ? 0 : mv720 ? 2 : 0;
        #else
        /* 720p: H=726+1, last valid line at y=723, 3 white lines at bottom */
        /* 1080p: H=1189+1, 2 white lines at bottom */
        /* x5 zoom: H=1107+1, no bad lines at bottom; 1108-28=1080 */
        /* 1080 crop: H=1059+1, no bad lines at bottom */
        skip_bottom = zoom ? 0 : mv1080crop ? 0 : mv720 ? 3 : 2;
        #endif
        #endif

        #ifdef CONFIG_7D
        // FIXME: are these values correct for 720p and crop modes?
        skip_top    = 26;
        skip_left   = zoom ? 0 : 256;
        #endif

        #if defined(CONFIG_70D)
        skip_top    = 28;
        skip_left   = 144; // 146 could work, too
        skip_right  = zoom ? 0 : 8;
        #endif

        #ifdef CONFIG_7D2
        skip_top    = 0;
        skip_left   = 0;
        skip_left   = 0;
        skip_right  = 0;
        #endif

... some text here ..

names_are_hard

Nope, because I had no idea I should look there.  This code is really poorly organised.  There's different sensor size values in at least three different files, and they all interact.  Feels like a simpler system must be possible.  Why are some per cam values in platform/XXD, where you can find them, some are in src/random_file.c, where you can't, and some are in modules/random/random.c?  Ugh.

Thank you for coming back and teaching me this impossible ancient knowledge :)

The per cam stuff in raw.c should probably be moved into platform, right?

heder

Quote from: names_are_hard on February 04, 2024, 11:44:39 PM
Nope, because I had no idea I should look there.  This code is really poorly organised.  There's different sensor size values in at least three different files, and they all interact.  Feels like a simpler system must be possible.  Why are some per cam values in platform/XXD, where you can find them, some are in src/random_file.c, where you can't, and some are in modules/random/random.c?  Ugh.

Thank you for coming back and teaching me this impossible ancient knowledge :)

The per cam stuff in raw.c should probably be moved into platform, right?

It's kind of patching on patches, but no one took the time to fix it completely. The ML group was also very much result oriented, which is why we got result so fast (end users never really give us credit for good programming), but there is also a price to pay for that.  Alex did a great work, but even he could no do everything. And yes specific camera defines should go in platform/XXD.

... some text here ..

names_are_hard

200D raw video now works, using normal mlv_lite code.  You might find my changes helpful for some parts, on this branch: https://github.com/reticulatedpines/magiclantern_simplified/tree/200d_raw_draft
I'm expecting to change that branch before merging to dev, but not very much.

I can spend some more time on 7D2 if there are things I could do that would help?  I don't want to waste either of our time by duplicating work.

I've looked a little for EDMAC related stuff and it all seems to use RPC.

fe154724 is a function doing EDMAC stuff with Mossy, but very probably using RPC to do it.
fe255db8 might be CreateResLockEntry_RPC(int *, uint).  If so, d2000004 might be MMIO related to triggering the RPC.

I have however found something quite interesting and perhaps very useful.  I avoided the need to do a full edmac transfer on 200D because there's a convenience function that does a mem to mem copy using edmac region structs.  This is called in two places, some test code, and Vfx code.

Take a look at fe24ee8c - this function is Vfx related and has lots of mem to mem strings.  And it ends with a call to send_msg_to_Omar().  This might well be setting up for a copy that it's instructing Omar to run via edmac.  There are related functions around init and terminate Mem2Mem.  These also exist on 200D - but without RPC.  Since this is probably easier to understand than full edmac, and we only need mem to mem copies for raw video, getting this function working for us is something to consider.

heder

That is indeed interesting what you what you have found, keep digging. I only had a few minutes this morning to look and now in sitting in Copenhagen Airport waiting for next plane to Cairo. I wont have any time the next week, but i will be shooting some RAW video. After our trip I will continue and finalize the cleanup of my build also Ill convert some of the RAW footage and upload it to YouTube.
... some text here ..