Yi 4k+ bitrate mod and firmware unpacker.

Yes, it's on the soc but it only runs on one of the cores of the arm64 cpu and 66MB of ram.

I managed to figure out how to actually increase the dsp and core frequencies. There was an unused branch in the code that sets the clocks to what I assume are the default H2 clocks

writel 0x45d6b8 0xe1a00000 #nop
writel 0x45d6c4 0xea000025

Makes it go to that branch and sets the dsp to 696MHz and core to 552MHz which might be the real default values (camera sets them normally to 576MHz dsp and 432MHz core).

And since the branch it goes to has constants they can be changed by patching out the instructions in the branch:

Lowering the dsp to 432MHz

writel 0x45d760 0xE3A01B33
writel 0x45d768 0xE34119BF

or core to 324MHz

writel 0x45d764 0xE3A03CD9
writel 0x45d76c 0xE341334F

Makes the dsp crash (invalid fb_id in vin_util.c) when recording at 4k@60 but it works at 4k@30. Increasing it doesn't do anything to fix the crash with the 1080p@180 res which is a (run out of WARP_MCTF FB at vproc_prep.c) crash. MCTF means motion compensated temporal filter so I'm assuming since it's not a chip is too slow issue that there's something somewhere that's setting the amount of frames in that buffer to a too high amount.

It would be useful if someone could test if lowering the clocks of the dsp/core can save battery life when recording in modes that don't need much processing power.


awesome find irungentoo!!
I'll try to contribute a bit now, maybe it gets finding other things easier ;)

Here is the function you are patching, the pseudo c code with some renamed functions :
Code:
int __fastcall AmpEnc_SetSystemClock(_WORD *a1, int a2, int a3, int a4, __int16 a5, __int16 a6, __int16 a7, __int16 a8, int a9, int a10)
{
  _WORD *v10; // r4@1
  int v11; // r0@1
  int v12; // r5@1
  char _ZF; // zf@4
  char v14; // zf@7
  int v18; // r1@17
  int v19; // r2@17
  int v20; // r2@25
  int v21; // r3@25
  int v22; // r4@25
  int v23; // r0@26
  int v24; // r2@26
  int v25; // r3@26
  int v26; // r0@26
  int v27; // r2@26
  int v28; // r3@26
  signed int v30; // r0@32
  int var_CC; // [sp+8h] [bp-CCh]@17
  int var_C8; // [sp+Ch] [bp-C8h]@17
  int v33; // [sp+10h] [bp-C4h]@31
  signed int v34; // [sp+14h] [bp-C0h]@31
  signed int v35; // [sp+18h] [bp-BCh]@31
  signed int v36; // [sp+1Ch] [bp-B8h]@31
  signed int v37; // [sp+20h] [bp-B4h]@31
  signed int v38; // [sp+24h] [bp-B0h]@31
  signed int v39; // [sp+28h] [bp-ACh]@31
  char v40; // [sp+AFh] [bp-25h]@31

  v10 = a1;
  _ZF = a1 == 0;
  v11 = *a1;
  v12 = v10[1];
  if ( _ZF )
  {
    print_to_log(0x5C9F44, 0x71A164, 0x3C0, a4);// K_ASSERT at %s %d
    sub_1E8DD0();
    __asm { CPSID           IF }
    while ( 1 )
      ;
  }
  if ( !a3 )
  {
    print_to_log(0x5C9F44, 0x71A164, 0x3C1, a4);
    sub_1E8DD0();
    __asm { CPSID           IF }
    while ( 1 )
      ;
  }
  if ( !a4 )
  {
    print_to_log(0x5C9F44, 0x71A164, 0x3C2, 0);
    sub_1E8DD0();
    __asm { CPSID           IF }
    while ( 1 )
      ;
  }
  _ZF = a6 == 0;
  if ( a6 )
    _ZF = a5 == 0;
  if ( _ZF )
    goto LABEL_41;
  v14 = a8 == 0;
  if ( a8 )
    v14 = a7 == 0;
  if ( v14 )
  {
LABEL_41:
    print_to_log(0x5C9F44, 0x71A164, 964, a4);
    sub_1E8DD0();
    __asm { CPSID           IF }
    while ( 1 )
      ;
  }
  if ( !a9 )
  {
    print_to_log(0x5C9F44, 0x71A164, 965, a4);
    sub_1E8DD0();
    __asm { CPSID           IF }
    while ( 1 )
      ;
  }
  if ( !a10 )
  {
    print_to_log(0x5C9F44, 0x71A164, 966, a4);
    sub_1E8DD0();
    __asm { CPSID           IF }
    while ( 1 )
      ;
  }
  v18 = v10[2];
  v19 = v10[3];
  var_C8 = 1000000 * v18;
  var_CC = 1000000 * v19;
  if ( v18 == 2 )
  {
    v30 = sub_4C29C4();
    v19 = v10[3];
    var_C8 = v30;
  }
  else if ( v18 == 1 || !v18 )
  {
    var_C8 = 1000000 * v11;
  }
  if ( v19 == 2 )
  {
    var_CC = sub_4C28EC();
  }
  else if ( v19 == 1 || !v19 )
  {
    var_CC = 1000000 * v12;
  }
  print_to_log(0x71A404, var_C8, v19, 0);       // [Desire]IDSP   freq: %d
  print_to_log(0x71A41C, var_CC, v20, v21);     // [Desire]Core   freq: %d
  v22 = AmbaPLL_SetOpMode((int)&var_CC);        // function at : 0x4C2E6C
  if ( v22 )
  {
    v40 = 0;
    v33 = 'abmA';
    v34 = '_LLP';
    v35 = 'OteS';
    v36 = 'doMp';
    v37 = ' )(e';
    v38 = 'liaf';
    v39 = '!de';
    v22 = 4294967295;
    print_to_log(0x71A254, (int)&dword_65CC6C, 0x71A164, 1082);// AmbaPLL_SetOpMode failed!
                                                // 71a164 : AmpEnc_SetSystemClock
  }
  else
  {
    v23 = sub_4C29C4();
    print_to_log(0x71A450, v23, v24, v25);      // [Actual]IDSP   freq: %d
    v26 = sub_4C28EC();
    print_to_log(0x71A468, v26, v27, v28);      // [Actual]Core   freq: %d
  }
  return v22;
}

Yes, it isnt just luck, this function is called AmpEnc_SetSystemClock, it relies on an internal function called AmbaPLL_SetOpMode, which I think it's the actual function changing the freqs.
 
It was too long to include here, so here the link https://github.com/wavepacket0/Xiaomi_Yi_4k_Plus/blob/master/research/function_names_1.3.11.txt

This is the internal function names dump, in which you can find AmpEnc_SetSystemClock also.
Just go where the dumped k_assert address is and rename the function belonging to that address as the dumped name.

Example for AmpEnc_SetSystemClock : K_ASSERT found @ 0x45D5EC -> 0x71A164 -> parent K_ASSERT function name :AmpEnc_SetSystemClock
Go to 0x45D5EC, which is belonging to function 45D588, which is AmpEnc_SetSystemClock


Knowing this, we can better focus the attention on particular functions and also be able to patch the way they works
 
Later I will update the fw toolkit to also dump where every string passed though the log function is referenced in the code
 
https://github.com/irungentoo/Xiaomi_Yi_4k_Camera/tree/master/4k+/increased_framerate

4k@70fps works when I overclock the dsp/core slightly.

Now I need to figure out why it's making this error when I try increasing it to 75fps.

[CORE:th6:104986] Assertion failure at /h2/work/ssyeh/default/branch/xiaoyi_Z18/ucode/src/orccode/vproc/vproc_prep.c:5919:
[CORE:th6:104987] VPROC[chan_0]: run out of PREV_C FB

Which looks a lot like the error when I try increasing the 1080p mode to 180fps

[CORE:th6:338656] Assertion failure at /h2/work/ssyeh/default/branch/xiaoyi_Z18/ucode/src/orccode/vproc/vproc_prep.c:5034:
[CORE:th6:338657] VPROC[chan_0]: run out of WARP_MCTF FB
 
what prevents these modes from being included !?
If you look on the sensor summary pdf, you will notice that there is nothing on it that suggests that it supports hdr. For photos I'm pretty sure there's a way to write a script that takes multiple pictures with different exposures in a row that you could then combine after into an HDR picture but for video I don't think so.
 
10bit video yours is also impossible?
it turns out that besides raising fps and bitrate, nothing from the camera can be pulled?
 
irungentoo ...

A small screen from my program.
This is a test version.
What am I doing wrong?
Unpacker_win_1 for me for Windows did not work.

 

Attachments

  • yi_4k_1.4.0.png
    yi_4k_1.4.0.png
    66 KB · Views: 39
Last edited:
No, I do not have anything working in your program.
In my program, I can open the firmware.
It is not difficult.
Rum section, everything else is the same.
 
5 seconds and the firmware title is open.
I am attaching the text format file.
 

Attachments

  • hdr.txt
    890 bytes · Views: 28
Back
Top