SRM job memory buffers

Started by a1ex, July 02, 2014, 08:55:00 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

a1ex

Interesting find: if you call FA_CreateTestImage more than once, you need to call FA_DeleteTestImage in the same order (otherwise it will fail):

So, this is OK:

    struct JobClass * job1 = (void*) call("FA_CreateTestImage");
    struct JobClass * job2 = (void*) call("FA_CreateTestImage");

    call("FA_DeleteTestImage", job1);
    call("FA_DeleteTestImage", job2);


but this will fail:

    struct JobClass * job1 = (void*) call("FA_CreateTestImage");
    struct JobClass * job2 = (void*) call("FA_CreateTestImage");

    call("FA_DeleteTestImage", job2);
    call("FA_DeleteTestImage", job1);


Another nice trick: each job object has a contiguous raw image buffer, usually more than 32MB. With shoot_malloc, the maximum contiguous size is less than 32MB (depending on your camera). To access this buffer:


    struct JobClass * job = (void*) call("FA_CreateTestImage");
    void* buf = (void*) call("FA_GetCrawBuf", job);
   
    /* use your buffer */

    call("FA_DeleteTestImage", job);


So, it looks like we have a way to allocate some more memory, which is very useful for raw video. How much, I don't know yet.

a1ex

The underlying call for memory allocation is SRM_AllocateMemoryResourceFor1stJob (called from CreateSkeltonJob, easy to find from strings). To double-check, its second argument has an offset that matches the one from GetImageBuffer.

To free the memory, call SRM_FreeMemoryResourceFor1stJob (it's called from DeleteSkeltonJob, but has no strings - identify it from its first argument).

Example for 5D2:

GetImageBuffer returns (arg0->off_0x4)->off_0xC68, aka MEM(MEM(arg0 + 0x4) + 0xC68).


SRM_AllocateMemoryResourceFor1stJob(cbr_function, 0xC68 + something)
if take_semaphore(*0x3CC0, 0x64) != 0:
    DebugMsg(0, 22, "[JOB ERROR] SRM_AllocateMemoryResourceFor1stJob failed [%#x]', ...)



if (arg0->off_0x4)->off_0xC68 != 0:
    SRM_FreeMemoryResourceFor1stJob((arg0->off_0x4)->off_0xC68, 0, 0)


Notes and caveats:
- you don't need to enter factory mode to use this
- this is independent from shoot_malloc (you can use both, and using one doesn't affect the size or free space from the other)
- you can't tell how much to allocate; the buffer size is fixed (it tells you how much you've got)
- as long as you have one such buffer allocated, you can't take regular pictures (ERR70), but LiveView works fine
- if there's no more free RAM, the allocation will be delayed until you free something failed calls will be dropped, just wait for 100ms
- on 5D3, you can allocate 3 such buffers at a time (39MB x 3 = 117MB extra). On 5D2 and 550D, only 2.

Syntax:

void SRM_AllocateMemoryResourceFor1stJob(void (*callback)(uint32_t opaque, void* raw_buffer, uint32_t raw_buffer_size), uint32_t opaque);
void SRM_FreeMemoryResourceFor1stJob(void* raw_buffer, uint32_t unk1_zero, uint32_t unk2_zero);

jimmyD30

@A1ex Reply #22

Strange that the order of deleting 'jobs' make a difference, I guess it relates to how the firmware prefers to manages memory?

Anyway... Mo' memory for raw video = :D

a1ex

Yeah, that was unexpected. The resource manager is quite complex; maybe g3gg0 will have a better understanding of why this happens.

Levas

Quote from: a1ex on July 02, 2014, 10:31:20 AM

- on 5D3, you can allocate 3 such buffers at a time (39MB x 3 = 117MB extra). On 5D2 and 550D, only 2.

Alex, are these 39MB buffers, additional on the already discovered memory buffers, used for fill-up with raw recording ?
The 6D has about 250MB of memory buffer with raw-recording at the moment.
The 250MB did already sound like the max, according to the point when burst mode slows down with raw photo mode.
raw images are like 35MB and the SD can write 40MB/s to the card.
Although there are reports of 9 seconds of writing to the SD card time to clear the buffer (with fast UHS-I card)in the 6D, so 40MB x 9 seconds is about 360MB of available buffer.

So there are probably 3 x 39MB buffers on the 6D. Would love to have these extra 117 MB for raw recording  :D

g3gg0

Quote from: a1ex on July 02, 2014, 10:31:20 AM
- on 5D3, you can allocate 3 such buffers at a time (39MB x 3 = 117MB extra). On 5D2 and 550D, only 2.

i made some changes to mlv_rec to support this new memory interface to make some tests.
it looks very promising. here some results:

5D3 v1.1.3:
Memory details: total 277 MiB [exmem 238 MiB, SRM 39 MiB] in 89 slots

7D v2.0.3:
Memory details: total 371 MiB [exmem 182 MiB, SRM 188 MiB] in 164 slots

600D v1.0.3:
Memory details: total 129 MiB [exmem 67 MiB, SRM 62 MiB] in 44 slots

this is another powerful push. thanks a lot, alex :)

Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

Levas

@Geggo,

Is there a way to test the changes you made to the mlv_rec module on a 6D (without the need to compile on my side  :-\) ?
At the moment, 6D is not supported in nightly builds...  :'(
I believe it's not as simple as put the new mlv_rec.mo file in an older nightly build, did tried that once, but it gives errors at camera startup.
Would love to have some extra memory with MLV recording  :)

g3gg0

hm i dont have a recent 6D firmware dump i could use to find the stubs.
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

a1ex

These changes are not yet included in any nightly build (we are reverse engineering it as we speak, and sharing the details as soon as we discover them). Please be patient, and hope this will motivate the 6D developers to bring the port up to date.

Some quick tests on 5D3 123, first outside LiveView, second in LV:

N/A

Quote from: g3gg0 on July 02, 2014, 09:50:43 PM

7D v2.0.3:
Memory details: total 371 MiB [exmem 182 MiB, SRM 188 MiB] in 164 slots

:o

Such amaze. Much wow.
7D. 600D. Rokinon 35 cine. Sigma 30 1.4
Audio and video recording/production, Random Photography
Want to help with the latest development but don't know how to compile?

nikfreak

Quote from: g3gg0 on July 02, 2014, 11:23:08 PM
hm i dont have a recent 6D firmware dump i could use to find the stubs.

Here you are. These are for 6D_113:

NSTUB(0xFF0F0098,  SRM_AllocateMemoryResourceFor1stJob)
NSTUB(0xFF0F40C8,  SRM_FreeMemoryResourceFor1stJob)
[size=8pt]70D.112 & 100D.101[/size]

a1ex

Thanks, you will probably have to find a few more tonight :)

nikfreak

Quote from: a1ex on July 03, 2014, 08:43:18 AM
Thanks, you will probably have to find a few more tonight :)

No problem I am continuously watching commits on butbucket...
[size=8pt]70D.112 & 100D.101[/size]

Levas

Silent picture discovery is huge.
But at this moment I'm way more excited about the possibility of getting some extra memory for MLV_rec  :P

Use MLV_rec a lot for high resolution short clips, these extra MB's mean a lot of extra seconds  :D



a1ex

Okay, here's an attempt to create some friendly wrappers for the new buffers: https://bitbucket.org/hudson/magic-lantern/pull-request/529

User-level API:
- srm_malloc_suite/srm_free_suite: will allocate the entire SRM memory (size autodetected) and return a memory suite, just like shoot_malloc_suite (preferred for raw_rec/mlv_rec)
- malloc/free: will use these buffers when you request very large sizes that can't be handled by shoot_malloc (32MB+); these are one level above srm_malloc_suite
- srm_malloc/srm_free: will use these buffers for any request higher than 25MB (even if the same buffers can be allocated from shoot_malloc)

Caveats:
- once somebody allocated from the SRM buffer, nobody else will be allowed to do so, and you will not be able to take pictures (this is because the backend must free the buffers in exactly the same order as allocated)
- you can, however, use malloc/free from two diferent tasks (first malloc will allocate all the SRM buffers, last free will give all buffers back to the system)
- with malloc, you can free the buffers in any order (the backend will take care of it)
- be careful allocating SRM buffers outside LiveView: you may not be able to enter LiveView until you free them
- depending on camera, some buffer sizes like 27MB may fail with malloc (because it will try shoot_malloc first, and it doesn't report the free space correctly [fixme]); workaround: srm_malloc will work.

For short-term processing that requires huge amounts of RAM, or for RAW recording, these wrappers should be just fine.

Porting notes:
- Stubs required: SRM_AllocateMemoryResourceFor1stJob, SRM_FreeMemoryResourceFor1stJob, CreateMemorySuite, DeleteMemorySuite, CreateMemoryChunk, AddMemoryChunk.
- Check the Free Memory dialog and post a screenshot (I already did for 5D3 123 earlier in this thread).
- Run the test from "don't click me" and post the screenshot created there.
- While this test is running, try taking some pictures (it should not crash, but the allocator may fail - it's normal, it should fail gracefully).

Some more thoughts:
g3gg0 is researching a way to merge two memory suites, so you would get the entire memory allocated in a single suite. With this, there would be - in theory - no need to modify the raw recording code, it would work out of the box.

However, if you enable the memory hack, it will allocate the memory outside LiveView and then get back into LiveView. The problem with this is that, if you allocate the entire RAM outside LV, the camera may not have enough RAM for the LiveView tasks (it happens on 5D3). So, I'd keep two separate allocators for now, and the user code will be responsible for having the proper context before calling (e.g. don't switch modes after allocating).

Audionut

Nice work.  Looking forward to see what can be done with all this extra RAM.  :)

nikfreak


So now see following. These are my findings for 6D_113:

NSTUB(0xFF0F0098,  SRM_AllocateMemoryResourceFor1stJob)
NSTUB(0xFF0F40C8,  SRM_FreeMemoryResourceFor1stJob)
NSTUB(0xFFCCE714 - RAM_OFFSET,  CreateMemoryChunk)
NSTUB(0xFFCCF210 - RAM_OFFSET,  AddMemoryChunk)


If you need others then just say so....
[size=8pt]70D.112 & 100D.101[/size]

kyrobb

I see that this has already been added to nightlies for the 7D, 5D3 and 600D. Any news on when the 550D can be tested?

a1ex

Nope, it wasn't (g3gg0 added the stubs without creating a branch first, and that triggered the nightly builds without any change in functionality)

Another note for raw recording: calling SRM_ChangeMemoryManagementForFactory might make a difference.

For example, for 550D, in LiveView, you get 75 + 1x31 MB in normal mode, and 43 + 3x31 in factory mode. 30MB extra is not bad, no?
On 5D2, in LiveView, you get 183 + 4x37 in normal mode, and 259 + 2x37 in factory mode (same with jpeg-small). No difference.
On 5D3, you get 163 + 3x39 in normal mode, and 127 + 4x39 in factory mode. No difference.

This might remove the need for picture quality tricks, at least on some cameras. Need to double-check if this is a persistent setting though.

(I'll let you continue the research during the next few weeks - sorry, family needs a little more attention, and it will keep me offline for a while)

dmilligan

1100D, I'm fairly certain these are right:

// NSTUB(    ???,  CreateMemorySuite)
NSTUB(0xFF071BD0,  DeleteMemorySuite)
// NSTUB(    ???,  CreateMemoryChunk)
NSTUB(0xFF072040,  AddMemoryChunk)

/** SRM JobMem **/
NSTUB(0xFF029268,  SRM_AllocateMemoryResourceFor1stJob)
NSTUB(0xFF02BCF0,  SRM_FreeMemoryResourceFor1stJob)


I'm having a little trouble with CreateMemorySuite and CreateMemoryChunk, I have some leads:

NSTUB(0xFF0715BC, CreateMemoryChunk)
NSTUB(0xFF071D9C, CreateMemorySuite)

but I'm not sure if these are right, or how to verify them, any hints?

sub_FF071D9C+20:   _malloc(24)
sub_FF071D9C+40:   sub_FF0142D8('pSuite', 'PackMemory\\PackMem.c', 554)
sub_FF071D9C+100:   sub_FF0715BC(arg0, arg1, arg2)


sub_FF0715BC+20:   _malloc(40)
sub_FF0715BC+40:   sub_FF0142D8('pChunk', 'PackMemory\\PackMem.c', 244)

dmilligan



the test fails but I guess that's because it's trying to allocate 25MB, and these are only 20MB on the 1100D?



Any interesting thing happened during the test: I tried to take some pics, they never got recorded to the SD card. If I tried to turn the camera off, it just kept saying "recording images", open the battery door and it says "don't take the battery out!", try to go into LV and it just says "busy...please wait" (maybe I have the stubs wrong?)

dmilligan

changed the test to 19MB, the first buffer works, but the second fails

dmilligan



holy sh*t!!!! 250MB more memory on the 60D!?

EDIT: 6x31MB in LV and Movie mode!

nikfreak

Quote from: g3gg0 on July 02, 2014, 09:50:43 PM
i made some changes to mlv_rec to support this new memory interface to make some tests.
it looks very promising. here some results:

5D3 v1.1.3:
Memory details: total 277 MiB [exmem 238 MiB, SRM 39 MiB] in 89 slots

7D v2.0.3:
Memory details: total 371 MiB [exmem 182 MiB, SRM 188 MiB] in 164 slots

600D v1.0.3:
Memory details: total 129 MiB [exmem 67 MiB, SRM 62 MiB] in 44 slots

this is another powerful push. thanks a lot, alex :)

after posting the missing stubs for 6D (see above), can anyone verify "SRM job total" for 6D? Could I find this out myself in QEMU w/o owning the cam?
Congrats dmilligan 250MB sounds amazing
[size=8pt]70D.112 & 100D.101[/size]

Pelican

Another exciting discovery...  :D Congrats!!!
EOS 7D Mark II, EOS 7D, EOS 5, EOS 100 + lenses (10mm to 300mm), 600EX, 550EX, YN600EX x 3
EOScard, EOS DSLR firmwares, ARMu, NiControl, etc.: http://pel.hu/down