From the day i ported ColorOS camera on OPO, i was curious about technique behind 50MP shot function. Today while trying to fix preview bug on COS12, i came to following line in log
E/QCameraParameters( 246): setSuperZoomMode:str_val:0,m_bSuperZoomEnabled:0
Recall that Oppo named 50MP shot function as SuperZoom feature. Besides, these lines are printed by HAL so obviously it took my attention. I started further investigation and found that HD Picture plug in was utilizing these two variables. By investigating a little bit i came to know that there are two parameters which are used to manipulate SuperZoom function. It's easy to enable by setting following two parameters high-resolution and superzoom. superzoom parameter accepts binary value (i.e 0 or 1) and high-resolution param has something great to do (can't tell for sure because this technique is not revealed publicly by Oppo. more information is given below). So now that is confirm that 50MP function is provided by HAL, that's why it doesn't work on OxygenOS but works on COS12 (if i'm not wrong both CM11s and COS12 HAL are same. More surprisingly, those are written by Oppo)So we just need to set two parameters to enable 50MP shots. I thought about testing it on CameraNext. I decompiled it and wasted much time on understanding f***ing cyngn's obfuscated code. But there was a surprise waiting for me. While finding proper place to inject my code i came to class com.android.camera.ap which basically checks preferences and sets camera parameters accordingly.I was surprised when i saw these parameters were already defined in some function
public static void c(Parameters parameters, boolean z) { if (!ap.j(parameters)) { return; } if (z) { parameters.setFlashMode("off"); ap.a(parameters, false); parameters.setPictureSize(4160, 3120); parameters.set("high-resolution", "1300"); parameters.set("superzoom", "0"); return; } parameters.set("high-resolution", "0"); parameters.set("superzoom", "0"); }
Now let me talk about how resolution is controlled in SuperZoom technique. It's too easy, it is controlled by high-resolution parameter provided by client. 1300 means 13MP and 5000 means 50MP (though i tried about 10000 value but it failed. Obviously there would be some guards in code :D)
So theoretical part ends here and now start injection of code into smali. As i told cyngn has obfuscated code of CameraNext so it is very hard to understand and implement. But another villain was ART. Yes ART was pain in a** while injecting code into smali because google decided not show much debugging messages when application is failed in compile time verification. Dalvik was showing dump of all registers in case of crash along with data types but ART just shows crash message. So it took longer than i expected.
Adding toggle was easy. I edited xml files under res/xml to add specific toggle for 50 MP. I decided to add 50MP functionality under Clear Image mode, This saved lots of my time. Now i just need to pass addition parameter with method c like
public static void c(Parameters parameters, boolean z, boolean z2) { if (!ap.j(parameters)) { return; } if (z) { parameters.setFlashMode("off"); ap.a(parameters, false); parameters.setPictureSize(4160, 3120); parameters.set("high-resolution", z2 ? "5000" : "1300"); parameters.set("superzoom", "0"); return; } parameters.set("high-resolution", "0"); parameters.set("superzoom", "0"); }boolean z2 acts as a toggle for 50MP feature.
The most frustrating part was neither CyanogenMod nor OnePlus ever told us that Clear Image was actually SuperZoom technique by Oppo. I don't know what kind of deal they have but at least they should have informed us.