vpp.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /*
  2. * AMLOGIC Audio/Video streaming port driver.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the named License,
  7. * or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  17. *
  18. * Author: Tim Yao <timyao@amlogic.com>
  19. *
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/err.h>
  23. #include <linux/vout/vinfo.h>
  24. #include <linux/amports/vframe.h>
  25. #include "video.h"
  26. #include "vpp.h"
  27. #include <linux/amports/vframe_provider.h>
  28. #ifdef CONFIG_AM_DEINTERLACE
  29. #include "deinterlace.h"
  30. #endif
  31. #include "videolog.h"
  32. //#define CONFIG_VIDEO_LOG
  33. #ifdef CONFIG_VIDEO_LOG
  34. #define AMLOG
  35. #endif
  36. #include <linux/amlog.h>
  37. /* vpp filter coefficients */
  38. #define COEF_BICUBIC 0
  39. #define COEF_3POINT_TRIANGLE 1
  40. #define COEF_4POINT_TRIANGLE 2
  41. #define COEF_BILINEAR 3
  42. const u32 vpp_filter_coefs_bicubic_sharp[] = {
  43. 3,
  44. 33 | 0x8000,
  45. // 0x01f80090, 0x01f80100, 0xff7f0200, 0xfe7f0300,
  46. 0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300,
  47. 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
  48. 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
  49. 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
  50. 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
  51. 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
  52. 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
  53. 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
  54. 0xf84848f8
  55. };
  56. const u32 vpp_filter_coefs_bicubic[] = {
  57. 4,
  58. 33,
  59. 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300,
  60. 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
  61. 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
  62. 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
  63. 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
  64. 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
  65. 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
  66. 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
  67. 0xf84848f8
  68. };
  69. const u32 vpp_filter_coefs_bilinear[] = {
  70. 4,
  71. 33,
  72. 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600,
  73. 0x00780800, 0x00760a00, 0x00740c00, 0x00720e00,
  74. 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600,
  75. 0x00681800, 0x00661a00, 0x00641c00, 0x00621e00,
  76. 0x00602000, 0x005e2200, 0x005c2400, 0x005a2600,
  77. 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,
  78. 0x00503000, 0x004e3200, 0x004c3400, 0x004a3600,
  79. 0x00483800, 0x00463a00, 0x00443c00, 0x00423e00,
  80. 0x00404000
  81. };
  82. const u32 vpp_filter_coefs_3point_triangle[] = {
  83. 3,
  84. 33,
  85. 0x40400000, 0x3f400100, 0x3d410200, 0x3c410300,
  86. 0x3a420400, 0x39420500, 0x37430600, 0x36430700,
  87. 0x35430800, 0x33450800, 0x32450900, 0x31450a00,
  88. 0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00,
  89. 0x2b470e00, 0x29480f00, 0x28481000, 0x27481100,
  90. 0x26491100, 0x25491200, 0x24491300, 0x234a1300,
  91. 0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600,
  92. 0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900,
  93. 0x1a4c1a00
  94. };
  95. const u32 vpp_filter_coefs_4point_triangle[] = {
  96. 4,
  97. 33,
  98. 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
  99. 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
  100. 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
  101. 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
  102. 0x18382808, 0x18382808, 0x17372909, 0x17372909,
  103. 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
  104. 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
  105. 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
  106. 0x10303010
  107. };
  108. static const u32 *filter_table[] = {
  109. vpp_filter_coefs_bicubic,
  110. vpp_filter_coefs_3point_triangle,
  111. vpp_filter_coefs_4point_triangle,
  112. vpp_filter_coefs_bilinear
  113. };
  114. static u32 vpp_wide_mode;
  115. static u32 vpp_zoom_ratio = 100;
  116. static s32 vpp_zoom_center_x, vpp_zoom_center_y;
  117. static u32 osd_layer_preblend=0;
  118. static s32 video_layer_top, video_layer_left, video_layer_width, video_layer_height;
  119. static s32 video_layer_global_offset_x, video_layer_global_offset_y;
  120. static s32 osd_layer_top,osd_layer_left,osd_layer_width,osd_layer_height;
  121. #define ZOOM_BITS 18
  122. #define PHASE_BITS 8
  123. /*
  124. * when ratio for Y is 1:1
  125. * Line # In(P) In(I) Out(P) Out(I) Out(P) Out(I)
  126. * 0 P_Y IT_Y P_Y IT_Y
  127. * 1 P_Y IT_Y
  128. * 2 IB_Y IB_Y
  129. * 3 IB_Y
  130. * 4 P_Y IT_Y P_Y IT_Y
  131. * 5 P_Y IT_Y
  132. * 6 IB_Y IB_Y
  133. * 7 IB_Y
  134. * 8 P_Y IT_Y P_Y IT_Y
  135. * 9 P_Y IT_Y
  136. * 10 IB_Y IB_Y
  137. * 11 IB_Y
  138. * 12 P_Y IT_Y P_Y IT_Y
  139. * P_Y IT_Y
  140. */
  141. /* The table data sequence here is arranged according to f2v_vphase_type_t enum,
  142. * IT2IT, IB2IB, T2IB, IB2IT, P2IT, P2IB, IT2P, IB2P, P2P
  143. */
  144. static const u8 f2v_420_in_pos[F2V_TYPE_MAX] =
  145. { 0, 2, 0, 2, 0, 0, 0, 2, 0 };
  146. static const u8 f2v_420_out_pos1[F2V_TYPE_MAX] =
  147. { 0, 2, 2, 0, 0, 2, 0, 0, 0 };
  148. static const u8 f2v_420_out_pos2[F2V_TYPE_MAX] =
  149. { 1, 3, 3, 1, 1, 3, 1, 1, 1 };
  150. static void f2v_get_vertical_phase(u32 zoom_ratio,
  151. u32 phase_adj,
  152. f2v_vphase_t vphase[F2V_TYPE_MAX],
  153. u32 interlace)
  154. {
  155. f2v_vphase_type_t type;
  156. s32 offset_in, offset_out;
  157. s32 phase;
  158. const u8 *f2v_420_out_pos;
  159. if ((interlace == 0) && (zoom_ratio > (1 << ZOOM_BITS))) {
  160. f2v_420_out_pos = f2v_420_out_pos2;
  161. } else {
  162. f2v_420_out_pos = f2v_420_out_pos1;
  163. }
  164. for (type = F2V_IT2IT; type < F2V_TYPE_MAX; type++) {
  165. offset_in = f2v_420_in_pos[type] << PHASE_BITS;
  166. offset_out =
  167. (f2v_420_out_pos[type] * zoom_ratio) >> (ZOOM_BITS -
  168. PHASE_BITS);
  169. if (offset_in > offset_out) {
  170. vphase[type].repeat_skip = -1; /* repeat line */
  171. vphase[type].phase =
  172. ((4 << PHASE_BITS) + offset_out - offset_in) >> 2;
  173. } else {
  174. vphase[type].repeat_skip = 0; /* skip line */
  175. while ((offset_in + (4 << PHASE_BITS)) <= offset_out) {
  176. vphase[type].repeat_skip++;
  177. offset_in += 4 << PHASE_BITS;
  178. }
  179. vphase[type].phase = (offset_out - offset_in) >> 2;
  180. }
  181. phase = vphase[type].phase + phase_adj;
  182. if (phase > 0x100) {
  183. vphase[type].repeat_skip++;
  184. }
  185. vphase[type].phase = phase & 0xff;
  186. if (vphase[type].repeat_skip > 5) {
  187. vphase[type].repeat_skip = 5;
  188. }
  189. }
  190. }
  191. static int
  192. vpp_process_speed_check(u32 width_in,
  193. u32 height_in,
  194. u32 height_out,
  195. u32 height_screen,vpp_frame_par_t *next_frame_par)
  196. {
  197. #if 0
  198. /* 1920x1080, 156M, with 0.90 full screen vertical scale output */
  199. get_sysclk() / 1560 *
  200. height_out / height_screen / 0.90 *
  201. 1920 * 1080 / width_in * height_in
  202. #endif
  203. if((height_in > 1080)&&(next_frame_par->vscale_skip_count== 0 )){
  204. return 1;
  205. }
  206. if (1800 * 1400 * height_out > height_screen * width_in * height_in) {
  207. return 0;
  208. }
  209. amlog_mask(LOG_MASK_VPP, "vpp_process_speed_check failed\n");
  210. return 1;
  211. }
  212. static void
  213. vpp_set_filters2(u32 width_in,
  214. u32 height_in,
  215. u32 width_out,
  216. u32 height_out,
  217. u32 aspect_ratio_out,
  218. u32 vpp_flags,
  219. vpp_frame_par_t *next_frame_par)
  220. {
  221. u32 screen_width, screen_height;
  222. s32 start, end;
  223. s32 video_top, video_left, temp;
  224. u32 video_width, video_height;
  225. u32 ratio_x = 0;
  226. u32 ratio_y = 0;
  227. vppfilter_mode_t *filter = &next_frame_par->vpp_filter;
  228. u32 wide_mode = vpp_flags & VPP_FLAG_WIDEMODE_MASK;
  229. s32 height_shift = 0;
  230. u32 height_after_ratio;
  231. u32 aspect_factor;
  232. s32 ini_vphase;
  233. #ifdef CONFIG_AM_DEINTERLACE
  234. int deinterlace_mode = get_deinterlace_mode();
  235. #endif
  236. next_frame_par->vscale_skip_count = 0;
  237. if (vpp_flags & VPP_FLAG_INTERLACE_IN) {
  238. next_frame_par->vscale_skip_count++;
  239. }
  240. if (vpp_flags & VPP_FLAG_INTERLACE_OUT) {
  241. height_shift++;
  242. }
  243. RESTART:
  244. aspect_factor = (vpp_flags & VPP_FLAG_AR_MASK) >> VPP_FLAG_AR_BITS;
  245. /* keep 8 bits resolution for aspect conversion */
  246. if (wide_mode == VIDEO_WIDEOPTION_4_3) {
  247. if(vpp_flags & VPP_FLAG_PORTRAIT_MODE)
  248. aspect_factor = 0x155;
  249. else
  250. aspect_factor = 0xc0;
  251. wide_mode = VIDEO_WIDEOPTION_NORMAL;
  252. }
  253. else if (wide_mode == VIDEO_WIDEOPTION_16_9) {
  254. if(vpp_flags & VPP_FLAG_PORTRAIT_MODE)
  255. aspect_factor = 0x1c7;
  256. else
  257. aspect_factor = 0x90;
  258. wide_mode = VIDEO_WIDEOPTION_NORMAL;
  259. }
  260. if ((aspect_factor == 0) || (wide_mode == VIDEO_WIDEOPTION_FULL_STRETCH)) {
  261. aspect_factor = 0x100;
  262. } else {
  263. aspect_factor = (width_in * height_out * aspect_factor << 3) /
  264. ((width_out * height_in * aspect_ratio_out) >> 5);
  265. }
  266. if(osd_layer_preblend)
  267. aspect_factor=0x100;
  268. height_after_ratio = (height_in * aspect_factor) >> 8;
  269. /* if we have ever set a cropped display area for video layer
  270. * (by checking video_layer_width/video_height), then
  271. * it will override the input width_out/height_out for
  272. * ratio calculations, a.k.a we have a window for video content
  273. */
  274. if(osd_layer_preblend){
  275. if ((osd_layer_width == 0) || (osd_layer_height == 0)) {
  276. video_top = 0;
  277. video_left = 0;
  278. video_width = width_out;
  279. video_height = height_out;
  280. } else {
  281. video_top = osd_layer_top;
  282. video_left = osd_layer_left;
  283. video_width = osd_layer_width;
  284. video_height = osd_layer_height;
  285. }
  286. } else {
  287. video_top = video_layer_top;
  288. video_left = video_layer_left;
  289. video_width = video_layer_width;
  290. video_height = video_layer_height;
  291. if ((video_top == 0) && (video_left == 0) && (video_width <= 1) && (video_height <= 1)) {
  292. /* special case to do full screen display */
  293. video_width = width_out;
  294. video_height = height_out;
  295. } else {
  296. if ((video_layer_width < 16) && (video_layer_height < 16)) {
  297. /* sanity check to move video out when the target size is too small */
  298. video_width = width_out;
  299. video_height = height_out;
  300. video_left = width_out * 2;
  301. }
  302. video_top += video_layer_global_offset_y;
  303. video_left+= video_layer_global_offset_x;
  304. }
  305. }
  306. screen_width = video_width * vpp_zoom_ratio / 100;
  307. screen_height = video_height * vpp_zoom_ratio / 100;
  308. ratio_x = (width_in << 18) / screen_width;
  309. if (ratio_x * screen_width < (width_in << 18)) {
  310. ratio_x++;
  311. }
  312. ratio_y = (height_after_ratio << 18) / screen_height;
  313. if (wide_mode == VIDEO_WIDEOPTION_NORMAL) {
  314. ratio_x = ratio_y = max(ratio_x, ratio_y);
  315. ratio_y = (ratio_y << 8) / aspect_factor;
  316. }
  317. else if (wide_mode == VIDEO_WIDEOPTION_NORMAL_NOSCALEUP) {
  318. u32 r1, r2;
  319. r1 = max(ratio_x, ratio_y);
  320. r2 = (r1 << 8) / aspect_factor;
  321. if ((r1 < (1<<18)) || (r2 < (1<<18))) {
  322. if (r1 < r2) {
  323. ratio_x = 1 << 18;
  324. ratio_y = (ratio_x << 8) / aspect_factor;
  325. } else {
  326. ratio_y = 1 << 18;
  327. ratio_x = aspect_factor << 10;
  328. }
  329. } else {
  330. ratio_x = r1;
  331. ratio_y = r2;
  332. }
  333. }
  334. /* vertical */
  335. ini_vphase = vpp_zoom_center_y & 0xff;
  336. next_frame_par->VPP_pic_in_height_ = height_in / (next_frame_par->vscale_skip_count + 1);
  337. /* screen position for source */
  338. start = video_top + video_height / 2 - ((height_in << 17) + (vpp_zoom_center_y << 10)) / ratio_y;
  339. end = (height_in << 18) / ratio_y + start - 1;
  340. /* calculate source vertical clip */
  341. if (video_top < 0) {
  342. if (start < 0) {
  343. temp = (-start * ratio_y) >> 18;
  344. next_frame_par->VPP_vd_start_lines_ = temp;
  345. } else {
  346. next_frame_par->VPP_vd_start_lines_ = 0;
  347. }
  348. } else {
  349. if (start < video_top) {
  350. temp = ((video_top - start) * ratio_y) >> 18;
  351. next_frame_par->VPP_vd_start_lines_ = temp;
  352. } else {
  353. next_frame_par->VPP_vd_start_lines_ = 0;
  354. }
  355. }
  356. if (vpp_flags & VPP_FLAG_INTERLACE_IN) {
  357. next_frame_par->VPP_vd_start_lines_ &= ~1;
  358. }
  359. temp = next_frame_par->VPP_vd_start_lines_ + (video_height * ratio_y >> 18);
  360. next_frame_par->VPP_vd_end_lines_ = (temp <= (height_in - 1)) ? temp : (height_in - 1);
  361. /* find overlapped region between
  362. * [start, end], [0, height_out-1], [video_top, video_top+video_height-1]
  363. */
  364. start = max(start, max(0, video_top));
  365. end = min(end, min((s32)height_out - 1, (s32)(video_top + video_height - 1)));
  366. if (start >= end) {
  367. /* nothing to display */
  368. next_frame_par->VPP_vsc_startp = 0;
  369. next_frame_par->VPP_vsc_endp = 0;
  370. } else {
  371. next_frame_par->VPP_vsc_startp =
  372. (vpp_flags & VPP_FLAG_INTERLACE_OUT) ? (start >> 1) : start;
  373. next_frame_par->VPP_vsc_endp =
  374. (vpp_flags & VPP_FLAG_INTERLACE_OUT) ? (end >> 1) : end;
  375. }
  376. /* set filter co-efficients */
  377. ratio_y <<= height_shift;
  378. ratio_y = ratio_y / (next_frame_par->vscale_skip_count + 1);
  379. if (vpp_flags & VPP_FLAG_INTERLACE_OUT) {
  380. filter->vpp_vert_coeff = filter_table[COEF_BILINEAR];
  381. } else {
  382. filter->vpp_vert_coeff = filter_table[COEF_BICUBIC];
  383. }
  384. #ifdef CONFIG_AM_DEINTERLACE
  385. if (deinterlace_mode) {
  386. filter->vpp_vert_coeff = filter_table[COEF_3POINT_TRIANGLE];
  387. }
  388. #endif
  389. filter->vpp_vsc_start_phase_step = ratio_y << 6;
  390. f2v_get_vertical_phase(ratio_y, ini_vphase,
  391. next_frame_par->VPP_vf_ini_phase_,
  392. vpp_flags & VPP_FLAG_INTERLACE_OUT);
  393. /* horizontal */
  394. /* set register to hardware reset default values when VPP scaler is working under
  395. * normal linear mode
  396. * VIDEO_WIDEOPTION_CINEMAWIDE case register value is set inside
  397. * calculate_non_linear_ratio()
  398. */
  399. filter->vpp_hf_start_phase_slope = 0;
  400. filter->vpp_hf_end_phase_slope = 0;
  401. filter->vpp_hf_start_phase_step = ratio_x << 6;
  402. next_frame_par->VPP_hsc_linear_startp = next_frame_par->VPP_hsc_startp;
  403. next_frame_par->VPP_hsc_linear_endp = next_frame_par->VPP_hsc_endp;
  404. filter->vpp_horz_coeff = filter_table[COEF_BICUBIC];
  405. filter->vpp_hsc_start_phase_step = ratio_x << 6;
  406. next_frame_par->VPP_hf_ini_phase_ = vpp_zoom_center_x & 0xff;
  407. if ((ratio_x == (1 << 18)) && (next_frame_par->VPP_hf_ini_phase_ == 0)) {
  408. filter->vpp_horz_coeff = vpp_filter_coefs_bicubic_sharp;
  409. } else {
  410. filter->vpp_horz_coeff = filter_table[COEF_BICUBIC];
  411. }
  412. /* screen position for source */
  413. start = video_left + video_width / 2 - ((width_in << 17) + (vpp_zoom_center_x << 10)) / ratio_x;
  414. end = (width_in << 18) / ratio_x + start - 1;
  415. /* calculate source horizontal clip */
  416. if (video_left < 0) {
  417. if (start < 0) {
  418. temp = (-start * ratio_x) >> 18;
  419. next_frame_par->VPP_hd_start_lines_ = temp;
  420. } else {
  421. next_frame_par->VPP_hd_start_lines_ = 0;
  422. }
  423. } else {
  424. if (start < video_left) {
  425. temp = ((video_left - start) * ratio_x) >> 18;
  426. next_frame_par->VPP_hd_start_lines_ = temp;
  427. } else {
  428. next_frame_par->VPP_hd_start_lines_ = 0;
  429. }
  430. }
  431. temp = next_frame_par->VPP_hd_start_lines_ + (video_width * ratio_x >> 18);
  432. next_frame_par->VPP_hd_end_lines_ = (temp <= (width_in - 1)) ? temp : (width_in - 1);
  433. next_frame_par->VPP_line_in_length_ = next_frame_par->VPP_hd_end_lines_ - next_frame_par->VPP_hd_start_lines_ + 1;
  434. /* find overlapped region between
  435. * [start, end], [0, width_out-1], [video_left, video_left+video_width-1]
  436. */
  437. start = max(start, max(0, video_left));
  438. end = min(end, min((s32)width_out - 1, (s32)(video_left + video_width - 1)));
  439. if (start >= end) {
  440. /* nothing to display */
  441. next_frame_par->VPP_hsc_startp = 0;
  442. next_frame_par->VPP_hsc_endp = 0;
  443. } else {
  444. next_frame_par->VPP_hsc_startp = start;
  445. next_frame_par->VPP_hsc_endp = end;
  446. }
  447. /* check the painful bandwidth limitation and see
  448. * if we need skip half resolution on source side for progressive
  449. * frames.
  450. */
  451. if ((next_frame_par->vscale_skip_count < 4) &&
  452. vpp_process_speed_check(next_frame_par->VPP_hd_end_lines_ - next_frame_par->VPP_hd_start_lines_ + 1,
  453. (next_frame_par->VPP_vd_end_lines_ - next_frame_par->VPP_vd_start_lines_ + 1) / (next_frame_par->vscale_skip_count + 1) ,
  454. next_frame_par->VPP_vsc_endp - next_frame_par->VPP_vsc_startp,
  455. height_out >> ((vpp_flags & VPP_FLAG_INTERLACE_OUT) ? 1 : 0),next_frame_par)) {
  456. if (vpp_flags & VPP_FLAG_INTERLACE_IN) {
  457. next_frame_par->vscale_skip_count += 2;
  458. } else {
  459. next_frame_par->vscale_skip_count++;
  460. }
  461. goto RESTART;
  462. }
  463. filter->vpp_hsc_start_phase_step = ratio_x << 6;
  464. next_frame_par->VPP_hf_ini_phase_ = vpp_zoom_center_x & 0xff;
  465. }
  466. void
  467. vpp_set_filters(u32 wide_mode,
  468. vframe_t *vf,
  469. vpp_frame_par_t *next_frame_par,
  470. const vinfo_t *vinfo)
  471. {
  472. u32 src_width = 0;
  473. u32 src_height = 0;
  474. u32 vpp_flags = 0;
  475. u32 aspect_ratio = 0;
  476. BUG_ON(vinfo == NULL);
  477. next_frame_par->VPP_post_blend_vd_v_start_ = 0;
  478. next_frame_par->VPP_post_blend_vd_h_start_ = 0;
  479. next_frame_par->VPP_postproc_misc_ = 0x200;
  480. /* check force ratio change flag in display buffer also
  481. * if it exist then it will override the settings in display side
  482. */
  483. if (vf->ratio_control & DISP_RATIO_FORCECONFIG) {
  484. if ((vf->ratio_control & DISP_RATIO_CTRL_MASK) == DISP_RATIO_KEEPRATIO) {
  485. if (wide_mode == VIDEO_WIDEOPTION_FULL_STRETCH) {
  486. wide_mode = VIDEO_WIDEOPTION_NORMAL;
  487. }
  488. } else {
  489. if (wide_mode == VIDEO_WIDEOPTION_NORMAL) {
  490. wide_mode = VIDEO_WIDEOPTION_FULL_STRETCH;
  491. }
  492. }
  493. }
  494. aspect_ratio = (vf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK)
  495. >> DISP_RATIO_ASPECT_RATIO_BIT;
  496. if (vf->type & VIDTYPE_INTERLACE) {
  497. vpp_flags = VPP_FLAG_INTERLACE_IN;
  498. }
  499. if(vf->ratio_control & DISP_RATIO_PORTRAIT_MODE){
  500. vpp_flags |= VPP_FLAG_PORTRAIT_MODE;
  501. }
  502. src_width = vf->width;
  503. src_height = vf->height;
  504. vpp_wide_mode = wide_mode;
  505. vpp_flags |= wide_mode | (aspect_ratio << VPP_FLAG_AR_BITS);
  506. if (vinfo->field_height != vinfo->height) {
  507. vpp_flags |= VPP_FLAG_INTERLACE_OUT;
  508. }
  509. next_frame_par->VPP_post_blend_vd_v_end_ = vinfo->field_height - 1;
  510. next_frame_par->VPP_post_blend_vd_h_end_ = vinfo->width - 1;
  511. next_frame_par->VPP_post_blend_h_size_ = vinfo->width;
  512. vpp_set_filters2(src_width,
  513. src_height,
  514. vinfo->width,
  515. vinfo->height,
  516. (vinfo->aspect_ratio_den << 8) / vinfo->aspect_ratio_num,
  517. vpp_flags,
  518. next_frame_par);
  519. }
  520. void vpp_set_osd_layer_preblend(u32 *enable)
  521. {
  522. osd_layer_preblend=*enable;
  523. }
  524. //para[0] x para[1] y para[2] w para[3] h
  525. void vpp_set_osd_layer_position(s32 *para)
  526. {
  527. if(IS_ERR_OR_NULL(&para[3]))
  528. {
  529. printk("para[3] is null\n");
  530. return ;
  531. }
  532. if(para[2] < 2 || para[3] < 2) return ;
  533. osd_layer_left=para[0];
  534. osd_layer_top=para[1];
  535. osd_layer_width=para[2];
  536. osd_layer_height=para[3];
  537. }
  538. void vpp_set_video_layer_position(s32 x, s32 y, s32 w, s32 h)
  539. {
  540. if ((w < 0) || (h < 0)) {
  541. return;
  542. }
  543. video_layer_left = x;
  544. video_layer_top = y;
  545. video_layer_width = w;
  546. video_layer_height = h;
  547. }
  548. void vpp_get_video_layer_position(s32 *x, s32 *y, s32 *w, s32 *h)
  549. {
  550. *x = video_layer_left;
  551. *y = video_layer_top;
  552. *w = video_layer_width;
  553. *h = video_layer_height;
  554. }
  555. void vpp_set_global_offset(s32 x, s32 y)
  556. {
  557. video_layer_global_offset_x = x;
  558. video_layer_global_offset_y = y;
  559. }
  560. void vpp_get_global_offset(s32 *x, s32 *y)
  561. {
  562. *x = video_layer_global_offset_x;
  563. *y = video_layer_global_offset_y;
  564. }
  565. void vpp_set_zoom_ratio(u32 r)
  566. {
  567. vpp_zoom_ratio = r;
  568. }
  569. u32 vpp_get_zoom_ratio(void)
  570. {
  571. return vpp_zoom_ratio;
  572. }