Advertisement
Guest User

Stabler

a guest
Sep 16th, 2012
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 48.02 KB | None | 0 0
  1. /** \file
  2. * Bitrate
  3. */
  4. #include "dryos.h"
  5. #include "bmp.h"
  6. #include "tasks.h"
  7. #include "debug.h"
  8. #include "menu.h"
  9. #include "property.h"
  10. #include "config.h"
  11. #include "gui.h"
  12. #include "lens.h"
  13. #include "cache_hacks.h"
  14.  
  15.  
  16. //----------------begin qscale-----------------
  17.  
  18. CONFIG_INT( "h264.qscale.plus16", qscale_plus16, 16-8 );
  19. CONFIG_INT( "h264.bitrate-mode", bitrate_mode, 1 ); // off, CBR, VBR
  20. CONFIG_INT( "h264.bitrate-factor", bitrate_factor, 20 );
  21. CONFIG_INT( "h264.iframe-factor", ifact, 10 );
  22. CONFIG_INT( "h264.pframe-factor", pfact, 10 );
  23.  
  24. CONFIG_INT( "h264.d1frame-factor", d1fact, 10 );
  25. CONFIG_INT( "h264.d2frame-factor", d2fact, 10 );
  26.  
  27. CONFIG_INT( "h264.gop0-factor", gop0fact, 10 );
  28. CONFIG_INT( "h264.gop1-factor", gop1fact, 10 );
  29. //CONFIG_INT( "h264.gop2-factor", gop2fact, 10 );
  30. CONFIG_INT( "h264.gop3-factor", gop3fact, 10 );
  31. CONFIG_INT( "h264.gop4-factor", gop4fact, 10 );
  32.  
  33. CONFIG_INT( "h264.paverage", paverage, 0 );
  34. CONFIG_INT( "h264.paverage", pdebug, 0 );
  35.  
  36. CONFIG_INT( "h264.dblockA", pdblock_A, 0 );
  37. CONFIG_INT( "h264.dblockB", pdblock_B, 0 );
  38.  
  39. CONFIG_INT( "h264.goplng", goplength, 12 );
  40. CONFIG_INT( "h264.picqpc", p_picqpc, 0 );
  41.  
  42. CONFIG_INT( "h264.qscale.slice", qscale_slice, 0 );
  43.  
  44.  
  45. CONFIG_INT( "time.indicator", time_indicator, 1); // 0 = off, 1 = current clip length, 2 = time remaining until filling the card, 3 = time remaining until 4GB
  46. CONFIG_INT( "bitrate.indicator", bitrate_indicator, 1);
  47.  
  48. int video_mode[5];
  49. PROP_HANDLER(PROP_VIDEO_MODE)
  50. {
  51. memcpy(video_mode, buf, 20);
  52. }
  53. int hacked=0;
  54.  
  55. //16 Slices
  56. int slice_array[] = { 0, 144, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86 };
  57.  
  58.  
  59. int time_indic_x = 720 - 160;
  60. int time_indic_y = 0;
  61. int time_indic_width = 160;
  62. int time_indic_height = 20;
  63. int time_indic_warning = 120;
  64. static int time_indic_font = FONT(FONT_MED, COLOR_RED, COLOR_BLACK );
  65.  
  66. int measured_bitrate = 0; // mbps
  67. //~ int free_space_32k = 0;
  68. int movie_bytes_written_32k = 0;
  69.  
  70. #define qscale (((int)qscale_plus16) - 16)
  71.  
  72. //#define qscalemin (((int)qscale_plusMin) - 41)
  73.  
  74. #define dblock_A (((int)pdblock_A) - 6)
  75. #define dblock_B (((int)pdblock_B) - 6)
  76. #define picqpc (((int)p_picqpc) - 7)
  77.  
  78. #define BL_INSTR(pc,dest) \
  79. ( 0xEB000000 \
  80. | ((( ((uint32_t)dest) - ((uint32_t)pc) - 8 ) >> 2) & 0x00FFFFFF) \
  81. )
  82.  
  83.  
  84.  
  85. int bitrate_dirty = 0;
  86.  
  87. // don't call those outside vbr_fix / vbr_set
  88. void mvrFixQScale(uint16_t *); // only safe to call when not recording
  89. void mvrSetDefQScale(int16_t *); // when recording, only change qscale by 1 at a time
  90. // otherwise ther appears a nice error message which shows the shutter count [quote AlinS] :)
  91. //void mvrSetDeblockingFilter(int32_t *, int32_t *); //-6 to 6
  92. #ifndef CONFIG_50D
  93.  
  94. void mvrSetDeblockingFilter(int32_t *);
  95. void JPCORE_DBFALPHA_DBFBETA(int8_t *, int8_t *);
  96. void mvrSetQscaleYC(int32_t *);
  97. void mvrSetLimitQScale(int32_t *);
  98. void AJ_JpcoreSliceqpdD_Qscale(int16_t *);
  99.  
  100. uint32_t hijack_func = 0;
  101. uint32_t hijack_handler(uint32_t parm1, uint32_t parm2, uint32_t parm3, uint32_t parm4)
  102. {
  103. uint32_t (*callee)(uint32_t, uint32_t, uint32_t, uint32_t) = hijack_func;
  104.  
  105. /* do stuff here */
  106. return callee(parm1, parm2, parm3, parm4);
  107. }
  108. void hijack_function(uint32_t address, uint32_t dest)
  109. {
  110. hijack_func = dest;
  111. cache_fake(address, BL_INSTR(address, &hijack_handler), TYPE_ICACHE);
  112. }
  113.  
  114. #endif
  115.  
  116.  
  117. static struct mvr_config mvr_config_copy;
  118. void cbr_init()
  119. {
  120. memcpy(&mvr_config_copy, &mvr_config, sizeof(mvr_config_copy));
  121. }
  122.  
  123. void vbr_fix(uint16_t param)
  124. {
  125. if (!lv) return;
  126. if (!is_movie_mode()) return;
  127. if (recording) return; // err70 if you do this while recording
  128.  
  129. mvrFixQScale(&param);
  130. }
  131.  
  132. void big_gop(int param)
  133. {
  134.  
  135.  
  136. video_mode[3] = param; //Gop Length
  137. prop_request_change(PROP_VIDEO_MODE, video_mode, 20);
  138.  
  139. // Edit this to play with Gop & Co.
  140. #ifndef CONFIG_50D
  141. #ifdef CONFIG_600D
  142. #define UNK_GOP_LOC 0xFF25516C
  143. #define GOP_MISMATCH_LOC 0xFF048054
  144. #elif defined CONFIG_1100D
  145. #define UNK_GOP_LOC 0xFF2478E8
  146. #define GOP_MISMATCH_LOC 0xFF047E4C
  147. #endif
  148. cache_fetch_line(UNK_GOP_LOC, TYPE_ICACHE);
  149. cache_fake(UNK_GOP_LOC , 0xE1A00000, TYPE_ICACHE);
  150.  
  151. // Movie "Gop Mismatch"
  152.  
  153. cache_fetch_line(GOP_MISMATCH_LOC, TYPE_ICACHE);
  154. cache_fake(GOP_MISMATCH_LOC , 0xE1A00000, TYPE_ICACHE);
  155.  
  156.  
  157. //hijack_function(0xFF25516C, 0xE1A00000);
  158. //hijack_function(0xFF254EC8, 0xeb0c4bde);
  159. #endif
  160. }
  161.  
  162.  
  163. void hack_slice()
  164.  
  165. {
  166. #ifdef CONFIG_600D
  167. #define SLICE_HACK_LEN 3
  168. #define SLICE_HACK_LOC {0xFF1CA5EC, 0xFF1CA144, 0xFF1C94A4}
  169. #elif defined(CONFIG_1100D)
  170. #define SLICE_HACK_LEN 3
  171. #define SLICE_HACK_LOC {0xFF1B8F74, 0xFF1B9BE0, 0xFF1BA0BC}
  172. #endif
  173. uint32_t slice_hacks[SLICE_HACK_LEN] = SLICE_HACK_LOC;
  174. for(int i=0;i<SLICE_HACK_LEN;++i) {
  175. cache_fetch_line(slice_hacks[i], TYPE_ICACHE); // Nop Slice Setting
  176. cache_fake(slice_hacks[i] , 0xE1A00000, TYPE_ICACHE);
  177. }
  178. hacked=1;
  179. }
  180.  
  181. void hack_deblock()
  182.  
  183. {
  184. //Nop Deblocking filter setting so it respects ours.
  185. // str:_GopSize__IOptSize2__POptSize2_DBF_A_DBF_B+924
  186. // DefQScale__D1__D2__IOptSize__POptSize__Opt
  187. #ifdef CONFIG_600D
  188. #define DEBLOCK_HACK_LEN 2
  189. #define DEBLOCK_HACK_LOC {0xFF1CA664, 0xFF1CA144}
  190. #elif defined(CONFIG_1100D)
  191. #define DEBLOCK_HACK_LEN 2
  192. #define DEBLOCK_HACK_LOC {0xFF1BA134, 0xFF1B9C14}
  193. #endif
  194. uint32_t deblock_hacks[DEBLOCK_HACK_LEN] = DEBLOCK_HACK_LOC;
  195. for(int i=0;i<DEBLOCK_HACK_LEN;++i) {
  196. cache_fetch_line(deblock_hacks[i], TYPE_ICACHE);
  197. cache_fake(deblock_hacks[i] , 0xE1A00000, TYPE_ICACHE);
  198. }
  199.  
  200. }
  201. void debugprints24p()
  202. {
  203. #ifdef CONFIG_600D
  204. if (video_mode[2] == 24)
  205. { int* xopt1 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 2 * MOV_OPT_STEP + 0;
  206. int* xopt2 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 2 * MOV_OPT_STEP + 1;
  207.  
  208. int* xdopt1 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 2 * MOV_OPT_STEP + 2;
  209. int* xdopt2 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 2 * MOV_OPT_STEP + 3;
  210.  
  211. int* xgopt0 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 2 * MOV_GOP_OPT_STEP + 0;
  212. int* xgopt1 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 2 * MOV_GOP_OPT_STEP + 1;
  213. int* xgopt2 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 2 * MOV_GOP_OPT_STEP + 2;
  214. int* xgopt3 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 2 * MOV_GOP_OPT_STEP + 3;
  215. int* xgopt4 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 2 * MOV_GOP_OPT_STEP + 4;
  216. bmp_printf(FONT_MED, 10,40, "I: %d P: %d D1: %d D2: %d", *xopt1, *xopt2, *xdopt1, *xdopt2);
  217. bmp_printf(FONT_MED, 10,80, "g0: %d g1: %d g2: %d g3: %d g4 %d", *xgopt0, *xgopt1, *xgopt2, *xgopt3, *xgopt4);
  218. }
  219.  
  220. if (video_mode[2] == 30)
  221. {
  222. int* xopt1 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 0 * MOV_OPT_STEP + 0;
  223. int* xopt2 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 0 * MOV_OPT_STEP + 1;
  224.  
  225. int* xdopt1 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 0 * MOV_OPT_STEP + 2;
  226. int* xdopt2 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + 0 * MOV_OPT_STEP + 3;
  227.  
  228. int* xgopt0 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 0 * MOV_GOP_OPT_STEP + 0;
  229. int* xgopt1 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 0 * MOV_GOP_OPT_STEP + 1;
  230. int* xgopt2 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 0 * MOV_GOP_OPT_STEP + 2;
  231. int* xgopt3 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 0 * MOV_GOP_OPT_STEP + 3;
  232. int* xgopt4 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 0 * MOV_GOP_OPT_STEP + 4;
  233. bmp_printf(FONT_MED, 10,40, "I: %d P: %d D1: %d D2: %d", *xopt1, *xopt2, *xdopt1, *xdopt2);
  234. bmp_printf(FONT_MED, 10,80, "g0: %d g1: %d g2: %d g3: %d g4 %d", *xgopt0, *xgopt1, *xgopt2, *xgopt3, *xgopt4);
  235. }
  236. /*
  237. int* xalpha = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 586; //0x929;
  238.  
  239. int* xbeta = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + 587; //0x92a;
  240.  
  241. int* xgops = (int*) &(mvr_config.gop_size_d);
  242.  
  243. int* xgopy = (int*) &(mvr_config.x124);
  244. int* xgopx = (int*) &(mvr_config.gop_zoneX);
  245. int* xgopz = (int*) &(mvr_config.gop_zoneZ);
  246.  
  247.  
  248. bmp_printf(FONT_SMALL, 10,40, "I: 0x%08X P: 0x%08X D1: %08X D2: %08X", xopt1, xopt2, xdopt1, xdopt2);
  249. bmp_printf(FONT_SMALL, 10,50, "g0: 0x%08X g1: 0x%08X g2: %08X g3: %08X g4 %08X", xgopt0, xgopt1, xgopt2, xgopt3, xgopt4);
  250.  
  251.  
  252. int* xspspps = (int*) (0xa083);
  253. int* xspspp2 = (int*) (0xa090);
  254. bmp_printf(FONT_MED, 10,180, "A083: %d A090: %d" , *xspspps, *xspspp2);
  255. //bmp_hexdump(FONT_SMALL, 0, 300, 0x6108, 32*10);
  256. // 786366719 2EDF00FF
  257.  
  258. bmp_printf(FONT_MED, 10,40, "I: %d P: %d D1: %d D2: %d", *xopt1, *xopt2, *xdopt1, *xdopt2);
  259. bmp_printf(FONT_MED, 10,80, "g0: %d g1: %d g2: %d g3: %d g4 %d", *xgopt0, *xgopt1, *xgopt2, *xgopt3, *xgopt4);
  260.  
  261. bmp_printf(FONT_MED, 10,120, "GP: %X v: %d U:%X v:%d" , xgops, *xgops, xgopy, *xgopy);
  262.  
  263. bmp_printf(FONT_MED, 10,160, "GX: %X v: %d GZ:%X v:%d" , xgopx, *xgopx, xgopz, *xgopz);
  264.  
  265.  
  266.  
  267. int* fooz=(int*)(0x5754);
  268. int* booz=(int*)(0x5750);
  269. int* dooz=(int*)(0xa083);
  270.  
  271. int* fooz=(int*)(0x6138); //a
  272. int* booz=(int*)(0xFF5DF584); //a0
  273. int* dooz=(int*)(0xFF5DF588); //78
  274.  
  275. uint16_t* fooz=(uint16_t*)(0x62A2); //a
  276. uint16_t* booz=(uint16_t*)(0x62A4); //a0
  277.  
  278. */
  279. int8_t* theqscale = (int8_t*) (0x6ce0);
  280. int16_t* defqscale = (int16_t*) (0x629A);
  281.  
  282.  
  283. bmp_printf(FONT_MED, 10,120, "Slice: %d DefQ: %d, QS: %d H: %d", *theqscale, *defqscale, qscale_slice, hacked);
  284.  
  285. /*
  286. int* xq1 = (int*) &(mvr_config.qscale_related_1);
  287. int* xq2 = (int*) &(mvr_config.qscale_related_2);
  288. int* xq3 = (int*) &(mvr_config.qscale_related_3);
  289.  
  290. bmp_printf(FONT_MED, 10,160, "Q1: %d Q2: %d Q3: %d" , *xq1, *xq2, *xq3);
  291. //65521
  292. int* xqq1 = (int*) &(mvr_config.another_def_q_scale);
  293. int* xqq2 = (int*) &(mvr_config.IniQScale);
  294. int* xqq3 = (int*) &(mvr_config.actual_qscale_maybe);
  295.  
  296. bmp_printf(FONT_MED, 10,200, "Def: %d INI: %d ACT: %d" , *xqq1, *xqq2, *xqq3);
  297.  
  298. int* xqq1 = (int*) (0x63F0);
  299. int* xqq2 = (int*) (0x63EC);
  300. int* xqq3 = (int*) (0x63E8);
  301. int* xqq4 = (int*) (0x63E4);
  302.  
  303. bmp_printf(FONT_MED, 10,200, "Def: %d INI: %d ACT: %d LS: %d" , *xqq1, *xqq2, *xqq3, *xqq4);
  304.  
  305. //0xFF5DF64C
  306.  
  307. 0x613C = arg0
  308. *0x6140 = (sp0->off_0x20)->off_0x8
  309. *0x614C = arg4
  310. *0x6158 = sp0->off_0x18
  311. *0x615C = sp0->off_0x20
  312. *0x6128 = (sp0->off_0x20)->off_0x4
  313. *0x6144 = arg3
  314. *0x6148 = arg4->off_0x8
  315. *0x6150 = arg4->off_0xC
  316.  
  317.  
  318. int* xqq1 = (int*) (0x613C);
  319. int* xqq2 = (int*) (0x614C);
  320. int* xqq3 = (int*) (0x6144);
  321. int* xqq4 = (int*) (0x615C);
  322. int* xqq5 = (int*) (0x6140);
  323.  
  324. bmp_printf(FONT_MED, 10,200, "Def: %d INI: %d ACT: %d LS: %d ad: %d" , *xqq1, *xqq2, *xqq3, *xqq4, *xqq5);
  325.  
  326.  
  327. int* xsz1 = (int*) (0x5754);
  328. int* xsz2 = (int*) (0x5750);
  329. bmp_printf(FONT_MED, 10,240, "Size1: %d Size2: %d", *xsz1, *xsz2);
  330. */
  331.  
  332.  
  333. #endif
  334. }
  335.  
  336.  
  337. #ifdef CONFIG_600D
  338. /*
  339. void gop_set(int den, int gopxscale, int gopyscale, int gopzscale)
  340. {
  341.  
  342. int* goptb3 = (int*) &(mvr_config.gop_zoneB);
  343. int* goptb4 = (int*) (int*) &(mvr_config_copy.gop_zoneB);
  344. (*goptb3) = (*goptb4) + 1;
  345.  
  346.  
  347.  
  348.  
  349. int* goptx3 = (int*) &(mvr_config.x124);
  350. int* goptx4 = (int*) (int*) &(mvr_config_copy.x124);
  351. (*goptx3) = (*goptx4) * gopxscale / den;
  352.  
  353. int* gopty3 = (int*) &(mvr_config.gop_zoneY);
  354. int* gopty4 = (int*) (int*) &(mvr_config_copy.gop_zoneY);
  355. (*gopty3) = (*gopty4) * gopyscale / den;
  356.  
  357. int* goptz3 = (int*) &(mvr_config.gop_zoneZ);
  358. int* goptz4 = (int*) (int*) &(mvr_config_copy.gop_zoneZ);
  359. (*goptz3) = (*goptz4) * gopzscale / den;
  360.  
  361.  
  362.  
  363. }
  364. */
  365.  
  366. #endif
  367.  
  368. // may be dangerous if mvr_config and numbers are incorrect
  369. void opt_set(int num, int den, int iscale, int pscale, int d1scale, int d2scale, int gop0scale, int gop1scale, int gop3scale, int gop4scale)
  370. {
  371. int i, j;
  372. #if !defined(CONFIG_5D2) && !defined(CONFIG_500D)
  373. int avgI=0;
  374. int avgP=0;
  375. int avd1=0;
  376. int avd2=0;
  377. int agop0=0;
  378. int agop1=0;
  379. // int agop2=0;
  380. int agop3=0;
  381. int agop4=0;
  382.  
  383. for ( int qq =0; qq < MOV_RES_AND_FPS_COMBINATIONS; qq++)
  384. { int* opt1 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + qq * MOV_OPT_STEP + 0;
  385. int* opt2 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + qq * MOV_OPT_STEP + 1;
  386.  
  387. int* dopt1 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + qq * MOV_OPT_STEP + 2;
  388. int* dopt2 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + qq * MOV_OPT_STEP + 3;
  389.  
  390. avd1 += (*dopt1) / (qq+1);
  391. avd2 += (*dopt2) / (qq+1);
  392. avgI += (*opt1) / (qq+1);
  393. avgP += (*opt2) / (qq+1);
  394.  
  395. int* gopt0 = (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + qq * MOV_GOP_OPT_STEP + 0;
  396. int* gopt1 = (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + qq * MOV_GOP_OPT_STEP + 1;
  397. // int* gopt2 = (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + qq * MOV_GOP_OPT_STEP + 2;
  398. int* gopt3 = (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + qq * MOV_GOP_OPT_STEP + 3;
  399. int* gopt4 = (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + qq * MOV_GOP_OPT_STEP + 4;
  400.  
  401. agop0+= (*gopt0) / (qq+1);
  402. agop1+= (*gopt1) / (qq+1);
  403. // agop2+= (*gopt2) / (qq+1);
  404. agop3+= (*gopt3) / (qq+1);
  405. agop4+= (*gopt4) / (qq+1);
  406. }
  407. #endif
  408. // 24P Defaults
  409. // I 62992200 (3c12F48) p 19594200 (12AFBD8)
  410. //d1 262144 = 40000 d2 262144
  411. //g0 3833856 (3A8000) g1 3309568 (328000) g2 2785284 (2A8004) g3 2260992 (228000) g4 17736704 (10EA400)
  412. //DSizes: 78643, 288358, 393216, 524288, 629145, 681574
  413.  
  414.  
  415. //G1-G2 = 80,000h
  416. //G2-G3 = 80,004h
  417. //Really High: 1.7, 1.7, 1.1 1.1 gop4 2.2 q-16
  418. //Stable BRS. 1,1, 2.5x2.5, 3x Many doesn't matter
  419. //Largest values: 1.9:1.0:1.5,1.5,2,2,1,2,2
  420. //100MBPS Crop 1250 , averaging P 1.7 vs 1.9
  421.  
  422.  
  423. for (i = 0; i < MOV_RES_AND_FPS_COMBINATIONS; i++) // 7 combinations of resolution / fps
  424. {
  425. #ifdef CONFIG_500D
  426. #define fullhd_30fps_opt_size_I fullhd_20fps_opt_size_I
  427. #define fullhd_30fps_gop_opt_0 fullhd_20fps_gop_opt_0
  428. #endif
  429.  
  430. #ifdef CONFIG_5D2
  431. #define fullhd_30fps_opt_size_I v1920_30fps_opt_size_I
  432. #endif
  433. #if !defined(CONFIG_5D2) && !defined(CONFIG_500D)
  434.  
  435. if (paverage == 1)
  436. {
  437. int* opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 0;
  438. (*opt) = avgI * iscale / den;
  439.  
  440. opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 1;
  441. (*opt) = avgP * pscale / den;
  442.  
  443. opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 2;
  444. (*opt) = avd1 * d1scale / den;
  445.  
  446. opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 3;
  447. (*opt) = avd2 * d2scale / den;
  448.  
  449.  
  450. opt = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 0;
  451. (*opt) = agop0 * gop0scale / den;
  452.  
  453. opt = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 1;
  454. (*opt) = agop1 * gop1scale / den;
  455.  
  456. //opt = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 2;
  457. //(*opt) = agop2 * gop2scale / den;
  458.  
  459. opt = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 3;
  460. (*opt) = agop3 * gop3scale / den;
  461.  
  462. opt = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 4;
  463. (*opt) = agop4 * gop4scale / den;
  464.  
  465.  
  466. }
  467. else
  468.  
  469. {
  470.  
  471.  
  472. int* opt3 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 0;
  473. int* opt4 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 0;
  474. (*opt3) = (*opt4) * iscale / den;
  475.  
  476. int* opt5 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 1;
  477. int* opt6 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 1;
  478. (*opt5) = (*opt6) * pscale / den;
  479.  
  480.  
  481. ///Dopts
  482.  
  483. int* dopt3 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 2;
  484. int* dopt4 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 2;
  485. (*dopt3) = (*dopt4) * d1scale / den;
  486.  
  487. int* dopt5 = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 3;
  488. int* dopt6 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 3;
  489. (*dopt5) = (*dopt6) * d2scale / den;
  490.  
  491. //gops
  492.  
  493. int* gopt0 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 0;
  494. int* gopt1 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 0;
  495. (*gopt0) = (*gopt1) * gop0scale / den;
  496.  
  497. int* gopt2 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 1;
  498. int* gopt3 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 1;
  499. (*gopt2) = (*gopt3) * gop1scale / den;
  500. int* gopt4 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 2;
  501. //int* gopt5 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 2;
  502. // (*gopt4) = (*gopt5) * gop2scale / den;
  503. //5570568 Gop 2 is calculated from P/I sizes.
  504. //7261685
  505.  
  506. int* gopt6 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 3;
  507. int* gopt7 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 3;
  508. (*gopt6) = (*gopt7) * gop3scale / den;
  509. int* gopt8 = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 4;
  510. int* gopt9 = (int*) (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + 4;
  511. (*gopt8) = (*gopt9) * gop4scale / den;
  512.  
  513.  
  514.  
  515.  
  516. }
  517.  
  518. #endif
  519.  
  520. /*
  521.  
  522. for (j = 0; j < MOV_OPT_NUM_PARAMS; j++)
  523. { int* opt0 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + j;
  524. if (*opt0 < 10000) { bmp_printf(FONT_LARGE, 0, 50, "opt_set: err %d %d %d ", i, j, *opt0); return; }
  525.  
  526. avg += (*opt0) / (i+1) ;
  527. }
  528.  
  529. int* opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP;
  530. (*opt) = avg * num / den;
  531. opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + 1;
  532. (*opt) = avg * num / den;
  533.  
  534. for (j = 0; j < MOV_OPT_NUM_PARAMS; j++)
  535. { int* opt0 = (int*) &(mvr_config_copy.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + j;
  536. int* opt = (int*) &(mvr_config.fullhd_30fps_opt_size_I) + i * MOV_OPT_STEP + j;
  537. if (*opt0 < 10000) { bmp_printf(FONT_LARGE, 0, 50, "opt_set: err %d %d %d ", i, j, *opt0); return; }
  538.  
  539. (*opt) = (*opt0) * num / den;
  540.  
  541. }*
  542.  
  543.  
  544. for (j = 0; j < MOV_GOP_OPT_NUM_PARAMS; j++)
  545. {
  546. int* opt0 = (int*) &(mvr_config_copy.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + j;
  547. int* opt = (int*) &(mvr_config.fullhd_30fps_gop_opt_0) + i * MOV_GOP_OPT_STEP + j;
  548. if (*opt0 < 10000) { bmp_printf(FONT_LARGE, 0, 50, "gop_set: err %d %d %d ", i, j, *opt0); return; }
  549. (*opt) = (*opt0) * num / den;
  550. }*/
  551. }
  552. }
  553. void bitrate_set()
  554. {
  555. if (!lv) return;
  556. if (!is_movie_mode()) return;
  557. if (gui_menu_shown()) return;
  558. if (recording) return;
  559.  
  560. #ifdef CONFIG_5D3
  561. //~ MEM(0x27880) = bitrate * 10000000;
  562. return;
  563. #endif
  564.  
  565. if (bitrate_mode == 0)
  566. {
  567. if (!bitrate_dirty) return;
  568. vbr_fix(0);
  569. opt_set(1,1,1,1,1,1,1,1,1,1);
  570. }
  571. else if (bitrate_mode == 1) // CBR
  572. {
  573. if (bitrate_factor == 10 && !bitrate_dirty) return;
  574. vbr_fix(0);
  575.  
  576. opt_set(bitrate_factor, 10, ifact, pfact, d1fact, d2fact, gop0fact, gop1fact, gop3fact, gop4fact);
  577.  
  578. hack_deblock();
  579.  
  580. if (qscale_slice != 0) { hack_slice(); }
  581.  
  582.  
  583.  
  584. int8_t* xalpha = (int8_t*) (0x6ce1);
  585. int8_t* xbeta = (int8_t*) (0x6ce2);
  586.  
  587. int8_t* xpicqpy = (int8_t*) (0x6ce3);
  588. int8_t* xpicqpc = (int8_t*) (0x6ce4);
  589. /*
  590. int16_t* sliceqpd = qscalemin;
  591.  
  592. AJ_JpcoreSliceqpdD_Qscale(&sliceqpd);
  593. */
  594. int dbarg[2];
  595. dbarg[0] = dblock_A;
  596. dbarg[1] = dblock_B;
  597.  
  598. int ycarg[2];
  599. ycarg[0] = -12;
  600. ycarg[1] = picqpc; //58 Highest value before Freezing@26 QPY
  601.  
  602. #ifndef CONFIG_1100D
  603. mvrSetDeblockingFilter(&dbarg);
  604.  
  605. mvrSetQscaleYC(&ycarg); // Set Qscale luma/chroma picQ
  606. #endif
  607.  
  608. if (picqpc == 0) { *xpicqpy=20; /*highest value without frying.*/ }
  609. else { *xpicqpy=26; /*highest value without frying.*/ }
  610.  
  611. /*
  612. int qlarg[2];
  613. qlarg[0] = 0;
  614. qlarg[1] = 6;
  615.  
  616. mvrSetLimitQScale(&qlarg);
  617.  
  618. */
  619. //uint16_t* xqscalem=(uint16_t*)(0x62A2);
  620. //*xqscalem=2;
  621.  
  622.  
  623. //int8_t* xalpha;
  624. //int8_t* xbeta;
  625.  
  626.  
  627. //*(int8_t*)0x6CE1 = xalpha;
  628. //*(int8_t*)0x6CE2 = xbeta;
  629.  
  630. //int* xBitrate=(int*)(0x1E44);
  631. /*
  632. int8_t* theboss = (int8_t*) (0x6ce0);
  633. bmp_printf(FONT_MED, 10,20, "Py: %d PC: %d Addr %X", *xpicqpy, *xpicqpc, *theboss);
  634. //bmp_printf(FONT_MED, 10,20, "Py: %d PC: %d GopL %d BR: %d", *xpicqpy, *xpicqpc, video_mode[3], *xBitrate);
  635.  
  636.  
  637. //bmp_hexdump(FONT_SMALL, 0, 300, 0x6108, 32*10);
  638. //*xBitrate= 10417124;
  639. //9417124 Default
  640.  
  641. /*
  642. bmp_printf(FONT_MED, 0, 300, "PROP_VIDEO_MODE: %d | %d | %d | %d", *fooz, *booz, video_mode[2], video_mode[3]);
  643. */
  644. big_gop(goplength);
  645. bmp_printf(FONT_MED, 10,20, "Py: %d PC: %d GopL %d", *xpicqpy, *xpicqpc, video_mode[3]);
  646.  
  647.  
  648.  
  649. }
  650. else if (bitrate_mode == 2) // QScale
  651. {
  652. vbr_fix(1);
  653. // opt_set(1,1,1,1);
  654.  
  655. opt_set(bitrate_factor, 10, ifact, pfact, d1fact, d2fact, gop0fact, gop1fact, gop3fact, gop4fact);
  656.  
  657.  
  658. hack_deblock();
  659.  
  660. int16_t q = qscale;
  661. mvrSetDefQScale(&q);
  662.  
  663. //int16_t* defqscale = (int16_t*) (0x629A);
  664. //*defqscale=-17;
  665. //int8_t* theqscale = (int8_t*) (0x6ce0);
  666. //*theqscale=70;
  667. //AJ_JpcoreSliceqpdD_Qscale(111);
  668. //EngDrvOut(0xC0F113C4, 0);
  669.  
  670. /*int qlarg[2];
  671. qlarg[0] = 0;
  672. qlarg[1] = 6;
  673.  
  674. mvrSetLimitQScale(&qlarg);
  675. */
  676. //uint16_t* xqscalem=(uint16_t*)(0x62A2);
  677. //*xqscalem=2;
  678. #ifndef CONFIG_1100D
  679.  
  680. int dbarg[2];
  681. dbarg[0] = dblock_A;
  682. dbarg[1] = dblock_B;
  683.  
  684. mvrSetDeblockingFilter(&dbarg);
  685.  
  686. int ycarg[2];
  687. ycarg[0] = -12;
  688. ycarg[1] = picqpc; //58 Highest value before Freezing@26 QPY
  689.  
  690. mvrSetQscaleYC(&ycarg); // Set Qscale luma/chroma picQ
  691.  
  692. #endif
  693.  
  694. int8_t* xpicqpy = (int8_t*) (0x6ce3);
  695. int8_t* xpicqpc = (int8_t*) (0x6ce4);
  696. if (picqpc == 0) { *xpicqpy=20; /*highest value without frying.*/ }
  697. else { *xpicqpy=26; /*highest value without frying.*/ }
  698.  
  699. big_gop(goplength); //Sets Gop Length
  700.  
  701. }
  702. bitrate_dirty = 1;
  703. }
  704.  
  705. static void
  706. bitrate_print(
  707. void * priv,
  708. int x,
  709. int y,
  710. int selected
  711. )
  712. {
  713. int fnt = selected ? MENU_FONT_SEL : MENU_FONT;
  714.  
  715. if (bitrate_mode == 0)
  716. {
  717. bmp_printf( fnt, x, y, "Bit Rate : FW default%s", bitrate_dirty ? "(reboot)" : "");
  718. menu_draw_icon(x, y, bitrate_dirty ? MNI_WARNING : MNI_OFF, 0);
  719. }
  720. else if (bitrate_mode == 1)
  721. {
  722. if (bitrate_factor > 10) fnt = FONT(fnt, bitrate_factor > 14 ? COLOR_RED : COLOR_YELLOW, FONT_BG(fnt));
  723. if (bitrate_factor < 7) fnt = FONT(fnt, bitrate_factor < 4 ? COLOR_RED : COLOR_YELLOW, FONT_BG(fnt));
  724. bmp_printf( fnt, x, y, "Bit Rate (CBR): %s%d.%dx%s", bitrate_factor>10 ? "up to " : "", bitrate_factor/10, bitrate_factor%10, bitrate_dirty || bitrate_factor != 10 ? "" : " (FW default)");
  725. menu_draw_icon(x, y, bitrate_dirty || bitrate_factor != 10 ? MNI_PERCENT : MNI_OFF, bitrate_factor * 100 / 30);
  726. }
  727. else if (bitrate_mode == 2)
  728. {
  729. fnt = FONT(fnt, COLOR_RED, FONT_BG(fnt));
  730. bmp_printf( fnt, x, y, "Bit Rate (VBR): QScale %d", qscale);
  731. menu_draw_icon(x, y, MNI_PERCENT, -(qscale-16) * 100 / 32);
  732. }
  733. }
  734.  
  735. void bitrate_mvr_log(char* mvr_logfile_buffer)
  736. {
  737. if (bitrate_mode == 1)
  738. {
  739. MVR_LOG_APPEND (
  740. "Bit Rate (CBR) : %d.%dx", bitrate_factor/10, bitrate_factor%10
  741. );
  742. }
  743. else if (bitrate_mode == 2)
  744. {
  745. MVR_LOG_APPEND (
  746. "Bit Rate (VBR) : QScale %d", qscale
  747. );
  748. }
  749. }
  750.  
  751. static void
  752. cbr_display(
  753. void * priv,
  754. int x,
  755. int y,
  756. int selected
  757. )
  758. {
  759. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "CBR factor : %d.%dx", bitrate_factor/10, bitrate_factor%10);
  760. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, bitrate_factor * 100 / 30);
  761. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  762. }
  763.  
  764.  
  765.  
  766. gfact0_display(
  767. void * priv,
  768. int x,
  769. int y,
  770. int selected
  771. )
  772. {
  773. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Gop0 factor : %d.%dx", gop0fact/10, gop0fact%10);
  774. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, gop0fact * 100 / 30);
  775. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  776. }
  777.  
  778.  
  779. gfact1_display(
  780. void * priv,
  781. int x,
  782. int y,
  783. int selected
  784. )
  785. {
  786. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Gop1 factor : %d.%dx", gop1fact/10, gop1fact%10);
  787. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, gop1fact * 100 / 30);
  788. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  789. }
  790. /*
  791. gfact2_display(
  792. void * priv,
  793. int x,
  794. int y,
  795. int selected
  796. )
  797. {
  798. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Gop2 factor : %d.%dx", gop2fact/10, gop2fact%10);
  799. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, gop2fact * 100 / 30);
  800. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  801. }
  802. */
  803.  
  804. gfact3_display(
  805. void * priv,
  806. int x,
  807. int y,
  808. int selected
  809. )
  810. {
  811. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Gop3 factor : %d.%dx", gop3fact/10, gop3fact%10);
  812. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, gop3fact * 100 / 30);
  813. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  814. }
  815.  
  816. gfact4_display(
  817. void * priv,
  818. int x,
  819. int y,
  820. int selected
  821. )
  822. {
  823. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Gop4 factor : %d.%dx", gop4fact/10, gop4fact%10);
  824. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, gop4fact * 100 / 30);
  825. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  826. }
  827.  
  828.  
  829. ifact_display(
  830. void * priv,
  831. int x,
  832. int y,
  833. int selected
  834. )
  835. {
  836. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "I factor : %d.%dx", ifact/10, ifact%10);
  837. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, ifact * 100 / 30);
  838. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  839. }
  840.  
  841. pfact_display(
  842. void * priv,
  843. int x,
  844. int y,
  845. int selected
  846. )
  847. {
  848. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "P factor : %d.%dx", pfact/10, pfact%10);
  849. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, pfact * 100 / 30);
  850. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  851. }
  852.  
  853.  
  854.  
  855.  
  856. d1fact_display(
  857. void * priv,
  858. int x,
  859. int y,
  860. int selected
  861. )
  862. {
  863. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "D1 factor : %d.%dx", d1fact/10, d1fact%10);
  864. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, d1fact * 100 / 30);
  865. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  866. }
  867.  
  868. d2fact_display(
  869. void * priv,
  870. int x,
  871. int y,
  872. int selected
  873. )
  874. {
  875. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "D2 factor : %d.%dx", d2fact/10, d2fact%10);
  876. if (bitrate_mode == 1) menu_draw_icon(x, y, MNI_PERCENT, d2fact * 100 / 30);
  877. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "CBR mode inactive => CBR setting not used.");
  878. }
  879.  
  880.  
  881.  
  882. static void
  883. qscale_display(
  884. void * priv,
  885. int x,
  886. int y,
  887. int selected
  888. )
  889. {
  890. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Qscale factor : %d", qscale);
  891. if (bitrate_mode == 2) menu_draw_icon(x, y, MNI_PERCENT, -(qscale-16) * 100 / 32);
  892. else menu_draw_icon(x, y, MNI_WARNING, (intptr_t) "VBR mode inactive");
  893. }
  894.  
  895.  
  896. static void
  897. qscale_slice_display(
  898. void * priv,
  899. int x,
  900. int y,
  901. int selected
  902. )
  903.  
  904. {
  905.  
  906. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "JP Slice : %d", slice_array[qscale_slice]);
  907.  
  908. }
  909.  
  910.  
  911. static void
  912. goplength_display(
  913. void * priv,
  914. int x,
  915. int y,
  916. int selected
  917. )
  918. {
  919. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, " Gop : %d", goplength);
  920. }
  921.  
  922. static void
  923. picqpc_display(
  924. void * priv,
  925. int x,
  926. int y,
  927. int selected
  928. )
  929. {
  930. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, " PicPC : %d", picqpc);
  931.  
  932.  
  933. }
  934.  
  935.  
  936. static void
  937. dblockA_display(
  938. void * priv,
  939. int x,
  940. int y,
  941. int selected
  942. )
  943. {
  944. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, " DblockA : %d", dblock_A);
  945.  
  946. menu_draw_icon(x, y, MNI_PERCENT, -(dblock_A-6) * 100 / 12);
  947. }
  948.  
  949.  
  950. static void
  951. dblockB_display(
  952. void * priv,
  953. int x,
  954. int y,
  955. int selected
  956. )
  957. {
  958. bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, " DblockB : %d", dblock_B);
  959.  
  960. menu_draw_icon(x, y, MNI_PERCENT, -(dblock_B-6) * 100 / 12);
  961. }
  962.  
  963.  
  964. static void
  965. bitrate_factor_toggle(void* priv, int delta)
  966. {
  967. if (recording) return;
  968. bitrate_factor = mod(bitrate_factor + delta - 1, 30) + 1;
  969. }
  970.  
  971. static void
  972. i_factor_toggle(void* priv, int delta)
  973. {
  974. if (recording) return;
  975. ifact = mod(ifact + delta - 1, 30) + 1;
  976. }
  977.  
  978. static void
  979. p_factor_toggle(void* priv, int delta)
  980. {
  981. if (recording) return;
  982. pfact = mod(pfact + delta - 1, 30) + 1;
  983. }
  984.  
  985.  
  986.  
  987. static void
  988. d1_factor_toggle(void* priv, int delta)
  989. {
  990. if (recording) return;
  991. d1fact = mod(d1fact + delta - 1, 30) + 1;
  992. }
  993.  
  994. static void
  995. d2_factor_toggle(void* priv, int delta)
  996. {
  997. if (recording) return;
  998. d2fact = mod(d2fact + delta - 1, 30) + 1;
  999. }
  1000.  
  1001. static void
  1002. gop0_factor_toggle(void* priv, int delta)
  1003. {
  1004. if (recording) return;
  1005. gop0fact = mod(gop0fact + delta - 1, 30) + 1;
  1006. }
  1007.  
  1008. static void
  1009. gop1_factor_toggle(void* priv, int delta)
  1010. {
  1011. if (recording) return;
  1012. gop1fact = mod(gop1fact + delta - 1, 30) + 1;
  1013. }
  1014. /*
  1015. static void
  1016. gop2_factor_toggle(void* priv, int delta)
  1017. {
  1018. if (recording) return;
  1019. gop2fact = mod(gop2fact + delta - 1, 30) + 1;
  1020. }
  1021. */
  1022. static void
  1023. gop3_factor_toggle(void* priv, int delta)
  1024. {
  1025. if (recording) return;
  1026. gop3fact = mod(gop3fact + delta - 1, 30) + 1;
  1027. }
  1028.  
  1029.  
  1030. static void
  1031. gop4_factor_toggle(void* priv, int delta)
  1032. {
  1033. if (recording) return;
  1034. gop4fact = mod(gop4fact + delta - 1, 30) + 1;
  1035. }
  1036.  
  1037. static void
  1038. goplength_toggle(void* priv, int delta)
  1039. {
  1040. if (recording) return;
  1041. goplength = mod(goplength - delta, 120);
  1042. }
  1043.  
  1044.  
  1045. static void
  1046. qscale_slice_toggle(void* priv, int delta)
  1047. {
  1048. if (recording) return;
  1049. qscale_slice = mod(qscale_slice - delta, 47);
  1050. }
  1051.  
  1052.  
  1053. static void
  1054. picqpc_toggle(void* priv, int delta)
  1055. {
  1056. if (recording) return;
  1057. p_picqpc = mod(p_picqpc - delta, 8);
  1058. }
  1059.  
  1060.  
  1061. static void
  1062. bitrate_dblockA_toggle(void* priv, int delta)
  1063. {
  1064. if (recording) return;
  1065. pdblock_A = mod(pdblock_A - delta, 13);
  1066. }
  1067.  
  1068. static void
  1069. bitrate_dblockB_toggle(void* priv, int delta)
  1070. {
  1071. if (recording) return;
  1072. pdblock_B = mod(pdblock_B - delta, 13);
  1073. }
  1074.  
  1075.  
  1076.  
  1077.  
  1078. static void
  1079. bitrate_qscale_toggle(void* priv, int delta)
  1080. {
  1081. if (recording) return;
  1082. qscale_plus16 = mod(qscale_plus16 - delta, 33);
  1083. }
  1084.  
  1085. static void
  1086. bitrate_toggle_mode(void* priv, int delta)
  1087. {
  1088. if (recording) return;
  1089. menu_ternary_toggle(priv, delta);
  1090. }
  1091.  
  1092. static void
  1093. bitrate_toggle(void* priv, int delta)
  1094. {
  1095. if (bitrate_mode == 1) bitrate_factor_toggle(priv, delta);
  1096. else if (bitrate_mode == 2) bitrate_qscale_toggle(priv, delta);
  1097. }
  1098.  
  1099.  
  1100. int movie_elapsed_time_01s = 0; // seconds since starting the current movie * 10
  1101.  
  1102. #ifdef CONFIG_5D3
  1103. extern int cluster_size;
  1104. extern int free_space_raw;
  1105. #else
  1106. PROP_INT(PROP_CLUSTER_SIZE, cluster_size);
  1107. PROP_INT(PROP_FREE_SPACE, free_space_raw);
  1108. #endif
  1109. #define free_space_32k (free_space_raw * (cluster_size>>10) / (32768>>10))
  1110.  
  1111.  
  1112. void free_space_show()
  1113. {
  1114. if (!get_global_draw()) return;
  1115. if (gui_menu_shown()) return;
  1116. if (recording && time_indicator) return;
  1117. int fsg = free_space_32k >> 15;
  1118. int fsgr = free_space_32k - (fsg << 15);
  1119. int fsgf = (fsgr * 10) >> 15;
  1120.  
  1121. bmp_printf(
  1122. FONT(SHADOW_FONT(FONT_MED), COLOR_WHITE, COLOR_BLACK),
  1123. time_indic_x + 160 - 6 * font_med.width,
  1124. time_indic_y,
  1125. "%d.%dGB",
  1126. fsg,
  1127. fsgf
  1128. );
  1129. }
  1130.  
  1131. void fps_show()
  1132. {
  1133. if (!get_global_draw()) return;
  1134. if (gui_menu_shown()) return;
  1135. if (!is_movie_mode() || recording) return;
  1136. //~ if (hdmi_code == 5) return; // workaround
  1137. int screen_layout = get_screen_layout();
  1138. if (screen_layout > SCREENLAYOUT_3_2_or_4_3) return;
  1139.  
  1140. /* bmp_printf(
  1141. SHADOW_FONT(FONT_MED),
  1142. time_indic_x + 160 - (video_mode_resolution == 0 ? 7 : 6) * font_med.width,
  1143. time_indic_y + font_med.height - 3,
  1144. "%d%s%s",
  1145. video_mode_fps,
  1146. video_mode_crop ? "+" : "p",
  1147. video_mode_resolution == 0 ? "1080" :
  1148. video_mode_resolution == 1 ? "720" : "VGA"
  1149. );*/
  1150.  
  1151. int f = fps_get_current_x1000();
  1152. bmp_printf(
  1153. SHADOW_FONT(FONT_MED),
  1154. time_indic_x + 160 - 6 * font_med.width,
  1155. time_indic_y + font_med.height - 3,
  1156. "%2d.%03d",
  1157. f / 1000, f % 1000
  1158. );
  1159. }
  1160.  
  1161. void free_space_show_photomode()
  1162. {
  1163. int fsg = free_space_32k >> 15;
  1164. int fsgr = free_space_32k - (fsg << 15);
  1165. int fsgf = (fsgr * 10) >> 15;
  1166. int x = time_indic_x + 2 * font_med.width;
  1167. int y = 452;
  1168. bmp_printf(
  1169. FONT(SHADOW_FONT(FONT_LARGE), COLOR_FG_NONLV, bmp_getpixel(x-10,y+10)),
  1170. x, y,
  1171. "%d.%dGB",
  1172. fsg,
  1173. fsgf
  1174. );
  1175. }
  1176.  
  1177. void time_indicator_show()
  1178. {
  1179. if (!get_global_draw()) return;
  1180.  
  1181. if (!recording)
  1182. {
  1183. free_space_show();
  1184. return;
  1185. }
  1186.  
  1187. // time until filling the card
  1188. // in "movie_elapsed_time_01s" seconds, the camera saved "movie_bytes_written_32k"x32kbytes, and there are left "free_space_32k"x32kbytes
  1189. int time_cardfill = movie_elapsed_time_01s * free_space_32k / movie_bytes_written_32k / 10;
  1190.  
  1191. // time until 4 GB
  1192. int time_4gb = movie_elapsed_time_01s * (4 * 1024 * 1024 / 32 - movie_bytes_written_32k) / movie_bytes_written_32k / 10;
  1193.  
  1194. //~ bmp_printf(FONT_MED, 0, 300, "%d %d %d %d ", movie_elapsed_time_01s, movie_elapsed_ticks, rec_time_card, rec_time_4gb);
  1195.  
  1196. // what to display
  1197. int dispvalue = time_indicator == 1 ? movie_elapsed_time_01s / 10:
  1198. time_indicator == 2 ? time_cardfill :
  1199. time_indicator == 3 ? MIN(time_4gb, time_cardfill)
  1200. : 0;
  1201.  
  1202. if (time_indicator)
  1203. {
  1204. bmp_printf(
  1205. time_4gb < time_indic_warning ? time_indic_font : FONT(FONT_MED, COLOR_WHITE, TOPBAR_BGCOLOR),
  1206. time_indic_x + 160 - 6 * font_med.width,
  1207. time_indic_y,
  1208. "%3d:%02d",
  1209. dispvalue / 60,
  1210. dispvalue % 60
  1211. );
  1212. }
  1213. if (bitrate_indicator)
  1214. {
  1215. bmp_printf( FONT_SMALL,
  1216. 680 - font_small.width * 5,
  1217. 55,
  1218. "A%3d ",
  1219. movie_bytes_written_32k * 32 * 80 / 1024 / (movie_elapsed_time_01s));
  1220.  
  1221. bmp_printf(FONT_SMALL,
  1222. 680 - font_small.width * 5,
  1223. 55 + font_small.height,
  1224. "B%3d ",
  1225. measured_bitrate*10
  1226. );
  1227.  
  1228. int fnts = FONT(FONT_SMALL, COLOR_WHITE, mvr_config.actual_qscale_maybe == -16 ? COLOR_RED : COLOR_BLACK);
  1229. bmp_printf(fnts,
  1230. 680,
  1231. 55 + font_small.height,
  1232. " Q%s%02d",
  1233. mvr_config.actual_qscale_maybe < 0 ? "-" : "+",
  1234. ABS(mvr_config.actual_qscale_maybe)
  1235. );
  1236. }
  1237.  
  1238. //~ if (flicker_being_killed()) // this also kills recording dot
  1239. //~ {
  1240. //~ maru(os.x_max - 28, os.y0 + 12, COLOR_RED);
  1241. //~ }
  1242. }
  1243.  
  1244. void measure_bitrate() // called once / second
  1245. {
  1246. static uint32_t prev_bytes_written = 0;
  1247. uint32_t bytes_written = MVR_BYTES_WRITTEN;
  1248. int bytes_delta = (((int)(bytes_written >> 1)) - ((int)(prev_bytes_written >> 1))) << 1;
  1249. prev_bytes_written = bytes_written;
  1250. movie_bytes_written_32k = bytes_written >> 15;
  1251. measured_bitrate = (ABS(bytes_delta) / 1024) * 8 / 1024;
  1252. }
  1253.  
  1254. static void
  1255. time_indicator_display( void * priv, int x, int y, int selected )
  1256. {
  1257. bmp_printf(
  1258. selected ? MENU_FONT_SEL : MENU_FONT,
  1259. x, y,
  1260. "Time Indicator: %s",
  1261. time_indicator == 1 ? "Elapsed" :
  1262. time_indicator == 2 ? "Remain.Card" :
  1263. time_indicator == 3 ? "Remain.4GB" : "OFF"
  1264. );
  1265. menu_draw_icon(x, y, MNI_BOOL_GDR(time_indicator));
  1266. }
  1267.  
  1268. /*static void
  1269. bitrate_indicator_display( void * priv, int x, int y, int selected )
  1270. {
  1271. bmp_printf(
  1272. selected ? MENU_FONT_SEL : MENU_FONT,
  1273. x, y,
  1274. "Bitrate Info : %s",
  1275. bitrate_indicator ? "ON" : "OFF"
  1276. );
  1277. menu_draw_icon(x, y, MNI_BOOL_GDR(bitrate_indicator));
  1278. }*/
  1279.  
  1280. CONFIG_INT("buffer.warning.level", buffer_warning_level, 70);
  1281. static void
  1282. buffer_warning_level_display( void * priv, int x, int y, int selected )
  1283. {
  1284. bmp_printf(
  1285. selected ? MENU_FONT_SEL : MENU_FONT,
  1286. x, y,
  1287. "BuffWarnLevel : %d%%",
  1288. buffer_warning_level
  1289. );
  1290. menu_draw_icon(x, y, MNI_PERCENT, buffer_warning_level);
  1291. }
  1292.  
  1293. static void buffer_warning_level_toggle(void* priv, int step)
  1294. {
  1295. buffer_warning_level += step;
  1296. if (buffer_warning_level > 100) buffer_warning_level = 30;
  1297. if (buffer_warning_level < 30) buffer_warning_level = 100;
  1298. }
  1299.  
  1300. int warning = 0;
  1301. int is_mvr_buffer_almost_full()
  1302. {
  1303. if (recording == 0) return 0;
  1304. if (recording == 1) return 1;
  1305. if (pdebug==1) { debugprints24p(); }
  1306. //Lock Slice
  1307. if ( (bitrate_mode == 1) && (qscale_slice !=0) )
  1308. { int8_t* theqscale = (int8_t*) (0x6ce0);
  1309. *theqscale=slice_array[qscale_slice];
  1310. }
  1311. if (MVR_BUFFER_USAGE > (int)buffer_warning_level) // Drop Slice if buffer
  1312. { if ( (bitrate_mode == 1) && (qscale_slice >4) )
  1313. qscale_slice -= 2;
  1314. }
  1315. if ( MVR_BUFFER_USAGE < ((int)buffer_warning_level-25) ) //Raise if BR getting low.
  1316. { if ( (bitrate_mode == 1) && (qscale_slice < 45) && ((measured_bitrate*10)<75) && (measured_bitrate!=0) )
  1317. qscale_slice++;
  1318. }
  1319.  
  1320. int ans = MVR_BUFFER_USAGE > (int)buffer_warning_level;
  1321. if (ans) warning = 1;
  1322. return warning;
  1323.  
  1324. }
  1325.  
  1326. void show_mvr_buffer_status()
  1327. {
  1328. int fnt = warning ? FONT(FONT_SMALL, COLOR_WHITE, COLOR_RED) : FONT(FONT_SMALL, COLOR_WHITE, COLOR_GREEN2);
  1329. if (warning) warning--;
  1330. if (recording && get_global_draw() && !gui_menu_shown()) bmp_printf(fnt, 680, 55, " %3d%%", MVR_BUFFER_USAGE);
  1331. }
  1332.  
  1333. static void load_h264_ini()
  1334. {
  1335. gui_stop_menu();
  1336. call("IVAParamMode", CARD_DRIVE "ML/H264.ini");
  1337. NotifyBox(2000, "%s", 0x4da10);
  1338. }
  1339.  
  1340. static void param_binary_toggle( void * priv, int delta )
  1341. {
  1342. unsigned * ptr = priv;
  1343. *ptr = !*ptr;
  1344. }
  1345.  
  1346. static void
  1347. param_display( void * priv, int x, int y, int selected )
  1348. {
  1349. unsigned fnt = selected ? MENU_FONT_SEL : MENU_FONT;
  1350. bmp_printf(
  1351. FONT(fnt, paverage ? COLOR_RED : FONT_FG(fnt), FONT_BG(fnt)),
  1352. x, y,
  1353. //23456789012
  1354. "Averaging : %s",
  1355. paverage ? "ON " : "OFF"
  1356. );
  1357. }
  1358.  
  1359.  
  1360. pdebug_display( void * priv, int x, int y, int selected )
  1361. {
  1362. unsigned fnt = selected ? MENU_FONT_SEL : MENU_FONT;
  1363. bmp_printf(
  1364. FONT(fnt, pdebug ? COLOR_RED : FONT_FG(fnt), FONT_BG(fnt)),
  1365. x, y,
  1366. //23456789012
  1367. "Debug : %s",
  1368. pdebug ? "ON " : "OFF"
  1369. );
  1370. }
  1371.  
  1372.  
  1373. static struct menu_entry mov_menus[] = {
  1374. #ifdef CONFIG_5D3
  1375. /* {
  1376. .name = "Bit Rate ",
  1377. .priv = &bitrate,
  1378. .min = 1,
  1379. .max = 20,
  1380. .help = "H.264 bitrate. One unit = 10 mb/s."
  1381. },*/
  1382. {
  1383. .name = "Load H264.ini ",
  1384. //~ .priv = &bitrate,
  1385. //~ .min = 1,
  1386. //~ .max = 20,
  1387. .select = load_h264_ini,
  1388. .help = "Bitrate settings"
  1389. },
  1390. #else
  1391.  
  1392. {
  1393. .name = "Encoder Options",
  1394. .select = menu_open_submenu,
  1395. .help = "Extra Encoder Options",
  1396. .children = (struct menu_entry[]) {
  1397.  
  1398.  
  1399.  
  1400. #ifndef CONFIG_500D
  1401. {
  1402. .name = "P Factor",
  1403. .priv = &pfact,
  1404. .select = p_factor_toggle,
  1405. .display = pfact_display,
  1406. .help = "1.0x = Canon default"
  1407. },
  1408.  
  1409.  
  1410. {
  1411. .name = "I Factor",
  1412. .priv = &ifact,
  1413. .select = i_factor_toggle,
  1414. .display = ifact_display,
  1415. .help = "1.0x = Canon default"
  1416. },
  1417.  
  1418. {
  1419. .name = "D1 Factor",
  1420. .priv = &d1fact,
  1421. .select = d1_factor_toggle,
  1422. .display = d1fact_display,
  1423. .help = "1.0x = Canon default"
  1424. },
  1425.  
  1426.  
  1427. {
  1428. .name = "D2 Factor",
  1429. .priv = &d2fact,
  1430. .select = d2_factor_toggle,
  1431. .display = d2fact_display,
  1432. .help = "1.0x = Canon default"
  1433. },
  1434.  
  1435. {
  1436. .name = "Gop0 Factor",
  1437. .priv = &gop0fact,
  1438. .select = gop0_factor_toggle,
  1439. .display = gfact0_display,
  1440. .help = "1.0x = Canon default"
  1441. },
  1442.  
  1443. {
  1444. .name = "Gop1 Factor",
  1445. .priv = &gop1fact,
  1446. .select = gop1_factor_toggle,
  1447. .display = gfact1_display,
  1448. .help = "1.0x = Canon default"
  1449. },
  1450. /* {
  1451. .name = "Gop2 Factor",
  1452. .priv = &gop2fact,
  1453. .select = gop2_factor_toggle,
  1454. .display = gfact2_display,
  1455. .help = "1.0x = Canon default"
  1456. },*/
  1457. {
  1458. .name = "Gop3 Factor",
  1459. .priv = &gop3fact,
  1460. .select = gop3_factor_toggle,
  1461. .display = gfact3_display,
  1462. .help = "1.0x = Canon default"
  1463. },
  1464.  
  1465. {
  1466. .name = "Gop4 Factor",
  1467. .priv = &gop4fact,
  1468. .select = gop4_factor_toggle,
  1469. .display = gfact4_display,
  1470. .help = "1.0x = Canon default"
  1471. },
  1472. #ifndef CONFIG_50D
  1473. {
  1474. .name = "SliceLck",
  1475. .priv = &qscale_slice,
  1476. .select = qscale_slice_toggle,
  1477. .display = qscale_slice_display,
  1478. .help = "Lock slice in CBR for max quality. 0 = off (reboot required)"
  1479. },
  1480. #endif
  1481.  
  1482.  
  1483.  
  1484. #endif
  1485.  
  1486.  
  1487. MENU_EOL
  1488. },
  1489. },
  1490.  
  1491. {
  1492. .name = "Bit Rate",
  1493. .priv = &bitrate_mode,
  1494. .display = bitrate_print,
  1495. .select = bitrate_toggle,
  1496. .help = "Change H.264 bitrate. Be careful, recording may stop!",
  1497. //.essential = 1,
  1498. .edit_mode = EM_MANY_VALUES,
  1499. .children = (struct menu_entry[]) {
  1500. {
  1501. .name = "Mode",
  1502. .priv = &bitrate_mode,
  1503. .max = 2,
  1504. .select = bitrate_toggle_mode,
  1505. .choices = (const char *[]) {"FW default", "CBR", "VBR (QScale)"},
  1506. .help = "Firmware default / CBR (recommended) / VBR (very risky)"
  1507. },
  1508. /* {
  1509. .name = "CBR factor",
  1510. .priv = &bitrate_factor,
  1511. .select = bitrate_factor_toggle,
  1512. .display = cbr_display,
  1513. .help = "1.0x = Canon default, 0.4x = 30minutes, 1.4x = fast card."
  1514. },*/
  1515. {
  1516. .name = "QScale",
  1517. .priv = &qscale_plus16,
  1518. .select = bitrate_qscale_toggle,
  1519. .display = qscale_display,
  1520. .help = "Quality factor (-16 = best quality). Try not to use it!"
  1521. },
  1522. #ifndef CONFIG_50D
  1523. {
  1524. .name = "Deblocking A",
  1525. .priv = &pdblock_A,
  1526. .select = bitrate_dblockA_toggle,
  1527. .display = dblockA_display,
  1528. .help = "Deblocking Alpha"
  1529. },
  1530.  
  1531. {
  1532. .name = "Deblocking B",
  1533. .priv = &pdblock_B,
  1534. .select = bitrate_dblockB_toggle,
  1535. .display = dblockB_display,
  1536. .help = "Deblocking Beta"
  1537. },
  1538. {
  1539. .name = "PicQ PC",
  1540. .priv = &p_picqpc,
  1541. .select = picqpc_toggle,
  1542. .display = picqpc_display,
  1543. .help = "If set to 0, PicQPy is maximum supported."
  1544. },
  1545. #endif
  1546. {
  1547. .name = "Gop Length",
  1548. .priv = &goplength,
  1549. .select = goplength_toggle,
  1550. .display = goplength_display,
  1551. .help = "Gop Length"
  1552. },
  1553. /*
  1554.  
  1555.  
  1556.  
  1557. {
  1558. .name = "Qscale Max",
  1559. .priv = &qscale_plusMax,
  1560. .select = qscale_max_toggle,
  1561. .display = qscale_max_display,
  1562. .help = "Max Qscale"
  1563. },
  1564.  
  1565. */
  1566.  
  1567.  
  1568.  
  1569.  
  1570. {
  1571. .name = "Bitrate Info",
  1572. .priv = &bitrate_indicator,
  1573. .max = 1,
  1574. .help = "A = average, B = instant bitrate, Q = instant QScale."
  1575. },
  1576. {
  1577. .name = "BuffWarnLevel",
  1578. .select = buffer_warning_level_toggle,
  1579. .display = buffer_warning_level_display,
  1580. .help = "ML will pause CPU-intensive graphics if buffer gets full."
  1581.  
  1582. },
  1583. {
  1584. .name = "Debugging",
  1585. .priv = &pdebug,
  1586. .select = param_binary_toggle,
  1587. .display = pdebug_display,
  1588. .help = "See encoder values on screen 24p/30p",
  1589. },
  1590.  
  1591.  
  1592.  
  1593. {
  1594. .name = "Averaging",
  1595. .priv = &paverage,
  1596. .select = param_binary_toggle,
  1597. .display = param_display,
  1598. .help = "Average Values for P/I",
  1599.  
  1600. },
  1601.  
  1602.  
  1603.  
  1604.  
  1605.  
  1606. MENU_EOL
  1607. },
  1608. },
  1609. #endif
  1610. #ifndef CONFIG_5D3
  1611. {
  1612. .name = "Time Indicator",
  1613. .priv = &time_indicator,
  1614. .select = menu_quaternary_toggle,
  1615. .display = time_indicator_display,
  1616. .help = "Time indicator during recording",
  1617. //.essential = 1,
  1618. //~ .edit_mode = EM_MANY_VALUES,
  1619. },
  1620. #endif
  1621. };
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629. void bitrate_init()
  1630. {
  1631. menu_add( "Movie", mov_menus, COUNT(mov_menus) );
  1632. }
  1633.  
  1634. INIT_FUNC(__FILE__, bitrate_init);
  1635.  
  1636. static void
  1637. bitrate_task( void* unused )
  1638. {
  1639. cbr_init();
  1640.  
  1641. TASK_LOOP
  1642. {
  1643.  
  1644. if (recording) msleep(100); // uses a bit of CPU, but it's precise
  1645. else msleep(500); // relax
  1646.  
  1647.  
  1648. // if (recording) wait_till_next_second(); // uses a bit of CPU, but it's precise
  1649. // else msleep(1000); // relax
  1650.  
  1651. if (recording)
  1652. {
  1653. // movie_elapsed_time_01s += 10;
  1654. movie_elapsed_time_01s += 1;
  1655. measure_bitrate();
  1656. BMP_LOCK( show_mvr_buffer_status(); )
  1657. }
  1658. else
  1659. {
  1660. movie_elapsed_time_01s = 0;
  1661. if (movie_elapsed_time_01s % 10 == 0)
  1662. bitrate_set();
  1663. }
  1664. }
  1665. }
  1666.  
  1667. void movie_indicators_show()
  1668. {
  1669. if (recording)
  1670. {
  1671. BMP_LOCK( time_indicator_show(); )
  1672. }
  1673. else
  1674. {
  1675. BMP_LOCK(
  1676. free_space_show();
  1677. fps_show();
  1678. )
  1679. }
  1680. }
  1681.  
  1682. TASK_CREATE("bitrate_task", bitrate_task, 0, 0x1d, 0x1000 );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement