blob: f39278b7cfb54874f666a20cc462baf2aeb5df95
1 | /* |
2 | * Copyright (c) 2014 Amlogic, Inc. All rights reserved. |
3 | * |
4 | * This source code is subject to the terms and conditions defined in the |
5 | * file 'LICENSE' which is part of this source code package. |
6 | * |
7 | * Description: |
8 | */ |
9 | |
10 | |
11 | |
12 | #define LOG_TAG "amavutils" |
13 | |
14 | #include <stdio.h> |
15 | #include <stdlib.h> |
16 | #include <string.h> |
17 | #include <fcntl.h> |
18 | #include <errno.h> |
19 | #include <string.h> |
20 | #include <strings.h> |
21 | #include <cutils/log.h> |
22 | #include <cutils/properties.h> |
23 | #include <sys/ioctl.h> |
24 | #include "include/Amvideoutils.h" |
25 | #include "include/Amsysfsutils.h" |
26 | #include "include/Amdisplayutils.h" |
27 | #include "include/Amsyswrite.h" |
28 | |
29 | #include "amports/amstream.h" |
30 | #include "ppmgr/ppmgr.h" |
31 | |
32 | #define SYSCMD_BUFSIZE 40 |
33 | #define DISP_DEVICE_PATH "/sys/class/video/device_resolution" |
34 | #define FB_DEVICE_PATH "/sys/class/graphics/fb0/virtual_size" |
35 | #define ANGLE_PATH "/dev/ppmgr" |
36 | #define VIDEO_PATH "/dev/amvideo" |
37 | #define VIDEO_AXIS_PATH "sys/class/video/axis" |
38 | #define PPMGR_ANGLE_PATH "sys/class/ppmgr/angle" |
39 | #define VIDEO_GLOBAL_OFFSET_PATH "/sys/class/video/global_offset" |
40 | #define FREE_SCALE_PATH "/sys/class/graphics/fb0/free_scale" |
41 | #define FREE_SCALE_PATH_FB2 "/sys/class/graphics/fb2/free_scale" |
42 | #define FREE_SCALE_PATH_FB1 "/sys/class/graphics/fb1/free_scale" |
43 | #define PPSCALER_PATH "/sys/class/ppmgr/ppscaler" |
44 | #define HDMI_AUTHENTICATE_PATH "/sys/module/hdmitx/parameters/hdmi_authenticated" |
45 | #define FREE_SCALE_MODE_PATH "/sys/class/graphics/fb0/freescale_mode" |
46 | #define WINDOW_AXIS_PATH "/sys/class/graphics/fb0/window_axis" |
47 | #define DISPLAY_AXIS_PATH "/sys/class/display/axis" |
48 | #define FREE_SCALE_AXIS_PATH "/sys/class/graphics/fb0/free_scale_axis" |
49 | #define PPSCALER_RECT "/sys/class/ppmgr/ppscaler_rect" |
50 | #define WINDOW_AXIS_PATH_FB1 "/sys/class/graphics/fb1/window_axis" |
51 | #define FREE_SCALE_AXIS_PATH_FB1 "/sys/class/graphics/fb1/free_scale_axis" |
52 | |
53 | static int rotation = 0; |
54 | static int disp_width = 1920; |
55 | static int disp_height = 1080; |
56 | |
57 | #ifndef LOGD |
58 | #define LOGV ALOGV |
59 | #define LOGD ALOGD |
60 | #define LOGI ALOGI |
61 | #define LOGW ALOGW |
62 | #define LOGE ALOGE |
63 | #endif |
64 | |
65 | //#define LOG_FUNCTION_NAME LOGI("%s-%d\n",__FUNCTION__,__LINE__); |
66 | #define LOG_FUNCTION_NAME |
67 | |
68 | int amvideo_utils_get_freescale_enable(void) |
69 | { |
70 | int ret = 0; |
71 | char buf[32]; |
72 | |
73 | ret = amsysfs_get_sysfs_str("/sys/class/graphics/fb0/free_scale", buf, 32); |
74 | if ((ret >= 0) && strncmp(buf, "free_scale_enalbe:[0x1]", |
75 | strlen("free_scale_enalbe:[0x1]")) == 0) { |
76 | |
77 | return 1; |
78 | |
79 | } |
80 | return 0; |
81 | } |
82 | |
83 | int amvideo_utils_get_global_offset(void) |
84 | { |
85 | LOG_FUNCTION_NAME |
86 | int offset = 0; |
87 | char buf[SYSCMD_BUFSIZE]; |
88 | int ret; |
89 | ret = amsysfs_get_sysfs_str(VIDEO_GLOBAL_OFFSET_PATH, buf, SYSCMD_BUFSIZE); |
90 | if (ret < 0) { |
91 | return offset; |
92 | } |
93 | if (sscanf(buf, "%d", &offset) == 1) { |
94 | LOGI("video global_offset %d\n", offset); |
95 | } |
96 | return offset; |
97 | } |
98 | |
99 | int is_video_on_vpp2(void) |
100 | { |
101 | int ret = 0; |
102 | |
103 | char val[PROPERTY_VALUE_MAX]; |
104 | memset(val, 0, sizeof(val)); |
105 | if (property_get("ro.vout.dualdisplay4", val, "false") |
106 | && strcmp(val, "true") == 0) { |
107 | memset(val, 0, sizeof(val)); |
108 | if (amsysfs_get_sysfs_str("/sys/module/amvideo/parameters/cur_dev_idx", val, sizeof(val)) == 0) { |
109 | if ((strncmp(val, "1", 1) == 0)) { |
110 | ret = 1; |
111 | } |
112 | } |
113 | } |
114 | |
115 | return ret; |
116 | } |
117 | |
118 | int is_vertical_panel(void) |
119 | { |
120 | int ret = 0; |
121 | |
122 | // ro.vout.dualdisplay4.ver-panel |
123 | char val[PROPERTY_VALUE_MAX]; |
124 | memset(val, 0, sizeof(val)); |
125 | if (property_get("ro.vout.dualdisplay4.ver-panel", val, "false") |
126 | && strcmp(val, "true") == 0) { |
127 | ret = 1; |
128 | } |
129 | |
130 | return ret; |
131 | } |
132 | |
133 | int is_screen_portrait(void) |
134 | { |
135 | int ret = 0; |
136 | |
137 | // ro.vout.dualdisplay4.ver-panel |
138 | char val[PROPERTY_VALUE_MAX]; |
139 | memset(val, 0, sizeof(val)); |
140 | if (property_get("ro.screen.portrait", val, "false") |
141 | && strcmp(val, "true") == 0) { |
142 | ret = 1; |
143 | } |
144 | |
145 | return ret; |
146 | } |
147 | |
148 | int is_osd_on_vpp2_new(void) |
149 | { |
150 | int ret = 0; |
151 | |
152 | char val[PROPERTY_VALUE_MAX]; |
153 | memset(val, 0, sizeof(val)); |
154 | if (amsysfs_get_sysfs_str("/sys/class/graphics/fb2/clone", val, sizeof(val)) == 0) { |
155 | ret = (val[19] == '1') ? 1 : 0; |
156 | } |
157 | return ret; |
158 | } |
159 | |
160 | int is_hdmi_on_vpp1_new(void) |
161 | { |
162 | int ret1 = 0; |
163 | int ret2 = 0; |
164 | int ret = 0; |
165 | |
166 | char val[PROPERTY_VALUE_MAX]; |
167 | memset(val, 0, sizeof(val)); |
168 | if (amsysfs_get_sysfs_str("/sys/class/graphics/fb1/ver_clone", val, sizeof(val)) == 0) { |
169 | ret1 = (val[11] == 'O') ? 1 : 0; |
170 | ret2 = (val[12] == 'N') ? 1 : 0; |
171 | if ((ret1 == 1) && (ret2 == 1)) { |
172 | ret = 1; |
173 | } |
174 | } |
175 | return ret; |
176 | } |
177 | |
178 | int is_vertical_panel_reverse(void) |
179 | { |
180 | int ret = 0; |
181 | |
182 | // ro.vout.dualdisplay4.ver-panel |
183 | char val[PROPERTY_VALUE_MAX]; |
184 | memset(val, 0, sizeof(val)); |
185 | if (property_get("ro.ver-panel.reverse", val, "false") |
186 | && strcmp(val, "true") == 0) { |
187 | ret = 1; |
188 | } |
189 | |
190 | return ret; |
191 | } |
192 | |
193 | int is_panel_mode(void) |
194 | { |
195 | int ret = 0; |
196 | char val[PROPERTY_VALUE_MAX]; |
197 | memset(val, 0, sizeof(val)); |
198 | if (amsysfs_get_sysfs_str("/sys/class/display/mode", val, sizeof(val)) == 0) { |
199 | ret = (val[0] == 'p') ? 1 : 0; |
200 | } |
201 | return ret; |
202 | } |
203 | |
204 | |
205 | typedef enum _OSD_DISP_MODE { |
206 | OSD_DISP_480I, |
207 | OSD_DISP_480P, |
208 | OSD_DISP_576I, |
209 | OSD_DISP_576P, |
210 | OSD_DISP_720P, |
211 | OSD_DISP_1080I, |
212 | OSD_DISP_1080P, |
213 | OSD_DISP_LVDS1080P, |
214 | } OSD_DISP_MODE; |
215 | |
216 | OSD_DISP_MODE get_osd_display_mode() |
217 | { |
218 | OSD_DISP_MODE ret = OSD_DISP_1080P; |
219 | char buf[PROPERTY_VALUE_MAX]; |
220 | memset(buf, 0, sizeof(buf)); |
221 | property_get("ubootenv.var.outputmode", buf, "1080p"); |
222 | if (!strncmp(buf, "720p", 4)) { |
223 | ret = OSD_DISP_720P; |
224 | } else if (!strncmp(buf, "480p", 4)) { |
225 | ret = OSD_DISP_480P; |
226 | } else if (!strncmp(buf, "480", 3)) { //for 480i&480cvbs |
227 | ret = OSD_DISP_480I; |
228 | } else if (!strncmp(buf, "576p", 4)) { |
229 | ret = OSD_DISP_576P; |
230 | } else if (!strncmp(buf, "576", 3)) { //for 576i&576cvbs |
231 | ret = OSD_DISP_576I; |
232 | } else if (!strncmp(buf, "1080i", 5)) { |
233 | ret = OSD_DISP_1080I; |
234 | } else if (!strncmp(buf, "1080p", 5)) { |
235 | ret = OSD_DISP_1080P; |
236 | } else if (!strncmp(buf, "lvds1080p", 9)) { |
237 | ret = OSD_DISP_LVDS1080P; |
238 | } |
239 | return ret; |
240 | } |
241 | |
242 | int get_device_win(OSD_DISP_MODE dismod, int *x, int *y, int *w, int *h) |
243 | { |
244 | const char *prop1080i_h = "ubootenv.var.1080i_h"; |
245 | const char *prop1080i_w = "ubootenv.var.1080i_w"; |
246 | const char *prop1080i_x = "ubootenv.var.1080i_x"; |
247 | const char *prop1080i_y = "ubootenv.var.1080i_y"; |
248 | |
249 | const char *prop1080p_h = "ubootenv.var.1080p_h"; |
250 | const char *prop1080p_w = "ubootenv.var.1080p_w"; |
251 | const char *prop1080p_x = "ubootenv.var.1080p_x"; |
252 | const char *prop1080p_y = "ubootenv.var.1080p_y"; |
253 | |
254 | const char *prop720p_h = "ubootenv.var.720p_h"; |
255 | const char *prop720p_w = "ubootenv.var.720p_w"; |
256 | const char *prop720p_x = "ubootenv.var.720p_x"; |
257 | const char *prop720p_y = "ubootenv.var.720p_y"; |
258 | |
259 | const char *prop480i_h = "ubootenv.var.480i_h"; |
260 | const char *prop480i_w = "ubootenv.var.480i_w"; |
261 | const char *prop480i_x = "ubootenv.var.480i_x"; |
262 | const char *prop480i_y = "ubootenv.var.480i_y"; |
263 | |
264 | const char *prop480p_h = "ubootenv.var.480p_h"; |
265 | const char *prop480p_w = "ubootenv.var.480p_w"; |
266 | const char *prop480p_x = "ubootenv.var.480p_x"; |
267 | const char *prop480p_y = "ubootenv.var.480p_y"; |
268 | |
269 | const char *prop576i_h = "ubootenv.var.576i_h"; |
270 | const char *prop576i_w = "ubootenv.var.576i_w"; |
271 | const char *prop576i_x = "ubootenv.var.576i_x"; |
272 | const char *prop576i_y = "ubootenv.var.576i_y"; |
273 | |
274 | const char *prop576p_h = "ubootenv.var.576p_h"; |
275 | const char *prop576p_w = "ubootenv.var.576p_w"; |
276 | const char *prop576p_x = "ubootenv.var.576p_x"; |
277 | const char *prop576p_y = "ubootenv.var.576p_y"; |
278 | |
279 | char prop_value_h[PROPERTY_VALUE_MAX]; |
280 | memset(prop_value_h, 0, PROPERTY_VALUE_MAX); |
281 | char prop_value_w[PROPERTY_VALUE_MAX]; |
282 | memset(prop_value_w, 0, PROPERTY_VALUE_MAX); |
283 | char prop_value_x[PROPERTY_VALUE_MAX]; |
284 | memset(prop_value_x, 0, PROPERTY_VALUE_MAX); |
285 | char prop_value_y[PROPERTY_VALUE_MAX]; |
286 | memset(prop_value_y, 0, PROPERTY_VALUE_MAX); |
287 | |
288 | switch (dismod) { |
289 | case OSD_DISP_1080P: |
290 | property_get(prop1080p_h, prop_value_h, "1080"); |
291 | property_get(prop1080p_w, prop_value_w, "1920"); |
292 | property_get(prop1080p_x, prop_value_x, "0"); |
293 | property_get(prop1080p_y, prop_value_y, "0"); |
294 | break; |
295 | case OSD_DISP_1080I: |
296 | property_get(prop1080i_h, prop_value_h, "1080"); |
297 | property_get(prop1080i_w, prop_value_w, "1920"); |
298 | property_get(prop1080i_x, prop_value_x, "0"); |
299 | property_get(prop1080i_y, prop_value_y, "0"); |
300 | break; |
301 | case OSD_DISP_LVDS1080P: |
302 | property_get(prop1080p_h, prop_value_h, "1080"); |
303 | property_get(prop1080p_w, prop_value_w, "1920"); |
304 | property_get(prop1080p_x, prop_value_x, "0"); |
305 | property_get(prop1080p_y, prop_value_y, "0"); |
306 | break; |
307 | case OSD_DISP_720P: |
308 | property_get(prop720p_h, prop_value_h, "720"); |
309 | property_get(prop720p_w, prop_value_w, "1280"); |
310 | property_get(prop720p_x, prop_value_x, "0"); |
311 | property_get(prop720p_y, prop_value_y, "0"); |
312 | break; |
313 | case OSD_DISP_576P: |
314 | property_get(prop576p_h, prop_value_h, "576"); |
315 | property_get(prop576p_w, prop_value_w, "720"); |
316 | property_get(prop576p_x, prop_value_x, "0"); |
317 | property_get(prop576p_y, prop_value_y, "0"); |
318 | break; |
319 | case OSD_DISP_576I: |
320 | property_get(prop576i_h, prop_value_h, "576"); |
321 | property_get(prop576i_w, prop_value_w, "720"); |
322 | property_get(prop576i_x, prop_value_x, "0"); |
323 | property_get(prop576i_y, prop_value_y, "0"); |
324 | break; |
325 | case OSD_DISP_480P: |
326 | property_get(prop480p_h, prop_value_h, "480"); |
327 | property_get(prop480p_w, prop_value_w, "720"); |
328 | property_get(prop480p_x, prop_value_x, "0"); |
329 | property_get(prop480p_y, prop_value_y, "0"); |
330 | break; |
331 | case OSD_DISP_480I: |
332 | property_get(prop480i_h, prop_value_h, "480"); |
333 | property_get(prop480i_w, prop_value_w, "720"); |
334 | property_get(prop480i_x, prop_value_x, "0"); |
335 | property_get(prop480i_y, prop_value_y, "0"); |
336 | break; |
337 | default : |
338 | break; |
339 | } |
340 | |
341 | LOGD("get_device_win h:%s , w:%s, x:%s, y:%s \n", prop_value_h, prop_value_w, prop_value_x, prop_value_y); |
342 | if (h) { |
343 | *h = atoi(prop_value_h); |
344 | } |
345 | if (w) { |
346 | *w = atoi(prop_value_w); |
347 | } |
348 | if (x) { |
349 | *x = atoi(prop_value_x); |
350 | } |
351 | if (y) { |
352 | *y = atoi(prop_value_y); |
353 | } |
354 | return 0; |
355 | } |
356 | |
357 | void get_axis(const char *path, int *x, int *y, int *w, int *h) |
358 | { |
359 | int fd = -1; |
360 | char buf[SYSCMD_BUFSIZE]; |
361 | if (amsysfs_get_sysfs_str(path, buf, sizeof(buf)) == 0) { |
362 | if (sscanf(buf, "%d %d %d %d", x, y, w, h) == 4) { |
363 | LOGI("%s axis: %d %d %d %d\n", path, *x, *y, *w, *h); |
364 | } |
365 | } |
366 | } |
367 | |
368 | int amvideo_convert_axis(int32_t* x, int32_t* y, int32_t* w, int32_t* h, int *rotation, int osd_rotation) |
369 | { |
370 | int fb0_w, fb0_h; |
371 | amdisplay_utils_get_size(&fb0_w, &fb0_h); |
372 | ALOGD("amvideo_convert_axis convert before %d,%d,%d,%d -- %d,%d", *x, *y, *w, *h, *rotation, osd_rotation); |
373 | /*if the video's width >= fb0_w and x == 0 , we think this a full screen video,then transfer the whole display size to decode |
374 | either is to y == 0 and hight >= fb0_h. |
375 | this is added for platforms which is 4:3 and hdmi mode are 16:9*/ |
376 | if (osd_rotation == 90) { |
377 | *rotation = (*rotation + osd_rotation) % 360; |
378 | int tmp = *w; |
379 | *w = *h; |
380 | *h = tmp; |
381 | |
382 | tmp = *y; |
383 | *y = *x; |
384 | *x = fb0_h - tmp - *w + 1; |
385 | } else if (osd_rotation == 270) { // 270 |
386 | *rotation = (*rotation + osd_rotation) % 360; |
387 | int tmp = *w; |
388 | *w = *h; |
389 | *h = tmp; |
390 | |
391 | tmp = *x; |
392 | *x = *y; |
393 | *y = fb0_w - tmp - *h + 1; |
394 | } else { |
395 | ALOGE("should no this rotation!"); |
396 | } |
397 | ALOGD("amvideo_convert_axis convert end %d,%d,%d,%d -- %d", *x, *y, *w, *h, *rotation); |
398 | return 0; |
399 | } |
400 | |
401 | void amvideo_setscreenmode() |
402 | { |
403 | |
404 | float wh_ratio = 0; |
405 | float ratio4_3 = 1.3333; |
406 | float ratio16_9 = 1.7778; |
407 | float offset = 0.2; |
408 | char val[PROPERTY_VALUE_MAX]; |
409 | memset(val, 0, sizeof(val)); |
410 | int enable_fullscreen = 1; |
411 | int default_screen_mode = -1; |
412 | |
413 | /*if(x<0 || y<0) |
414 | return;*/ |
415 | |
416 | if (property_get("tv.default.screen.mode", val, "-1") && (!(strcmp(val, "-1") == 0))) { |
417 | default_screen_mode = atoi(val); |
418 | if (default_screen_mode >= 0 && default_screen_mode <=3) { |
419 | amvideo_utils_set_screen_mode(default_screen_mode); |
420 | return ; |
421 | } |
422 | } |
423 | |
424 | int fs_x = 0, fs_y = 0, fs_w = 0, fs_h = 0; |
425 | get_axis(FREE_SCALE_AXIS_PATH, &fs_x, &fs_y, &fs_w, &fs_h); |
426 | |
427 | if (fs_h > fs_w) { |
428 | int i = fs_w; |
429 | fs_w = fs_h; |
430 | fs_h = i; |
431 | } |
432 | |
433 | if (fs_h > 0) { |
434 | wh_ratio = fs_w * (float)1.0 / fs_h; |
435 | } |
436 | |
437 | ALOGD("amvideo_setscreenmode as %f", wh_ratio); |
438 | if ((wh_ratio < (ratio4_3 + offset)) |
439 | && (wh_ratio > 0) |
440 | && (is_panel_mode() == 0)) { |
441 | amvideo_utils_set_screen_mode(1); |
442 | ALOGD("set screen mode as 1"); |
443 | }/*else{ |
444 | amvideo_utils_set_screen_mode(0); |
445 | ALOGD("set screen mode as 0"); |
446 | }*/ |
447 | } |
448 | |
449 | void set_scale(int x, int y, int w, int h, int *dst_x, int *dst_y, int *dst_w, int *dst_h, int disp_w, int disp_h) |
450 | { |
451 | float tmp_x,tmp_y,tmp_w,tmp_h; |
452 | tmp_x = (float)((float)((*dst_x) * w) / (float)disp_w); |
453 | tmp_y = (float)((float)((*dst_y) * h) / (float)disp_h); |
454 | tmp_w = (float)((float)((*dst_w) * w) / (float)disp_w); |
455 | tmp_h = (float)((float)((*dst_h) * h) / (float)disp_h); |
456 | *dst_x = (int)(tmp_x+0.5) + x; |
457 | *dst_y = (int)(tmp_y+0.5) + y; |
458 | *dst_w = (int)(tmp_w+0.5); |
459 | *dst_h = (int)(tmp_h+0.5); |
460 | } |
461 | |
462 | int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation) |
463 | { |
464 | LOG_FUNCTION_NAME |
465 | //for osd rotation, need convert the axis first |
466 | int osd_rotation = amdisplay_utils_get_osd_rotation(); |
467 | if (osd_rotation > 0) { |
468 | amvideo_convert_axis(&x, &y, &w, &h, &rotation, osd_rotation); |
469 | } |
470 | #if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 |
471 | // amSystemControlSetNativeWindowRect(x, y, w, h); |
472 | #endif |
473 | |
474 | int dev_w, dev_h, disp_w, disp_h, video_global_offset; |
475 | int dst_x, dst_y, dst_w, dst_h; |
476 | char buf[SYSCMD_BUFSIZE]; |
477 | int angle_fd = -1; |
478 | int ret = -1; |
479 | int axis[4]; |
480 | char enable_p2p_play[8] = {0}; |
481 | int video_on_vpp2_new = is_osd_on_vpp2_new(); |
482 | int screen_portrait = is_screen_portrait(); |
483 | int video_on_vpp2 = is_video_on_vpp2(); |
484 | int vertical_panel = is_vertical_panel(); |
485 | int vertical_panel_reverse = is_vertical_panel_reverse(); |
486 | #ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 |
487 | int hdmi_swith_on_vpp1 = is_hdmi_on_vpp1_new(); |
488 | #else |
489 | int hdmi_swith_on_vpp1 = !is_hdmi_on_vpp1_new(); |
490 | #endif |
491 | |
492 | if (video_on_vpp2) { |
493 | int fb0_w, fb0_h, fb2_w, fb2_h; |
494 | |
495 | amdisplay_utils_get_size(&fb0_w, &fb0_h); |
496 | amdisplay_utils_get_size_fb2(&fb2_w, &fb2_h); |
497 | |
498 | if (fb0_w > 0 && fb0_h > 0 && fb2_w > 0 && fb2_h > 0) { |
499 | if (vertical_panel) { |
500 | int x1, y1, w1, h1; |
501 | if (vertical_panel_reverse) { |
502 | x1 = (1.0 * fb2_w / fb0_h) * y; |
503 | y1 = (1.0 * fb2_h / fb0_w) * x; |
504 | w1 = (1.0 * fb2_w / fb0_h) * h; |
505 | h1 = (1.0 * fb2_h / fb0_w) * w; |
506 | } else { |
507 | x1 = (1.0 * fb2_w / fb0_h) * y; |
508 | y1 = (1.0 * fb2_h / fb0_w) * (fb0_w - x - w); |
509 | w1 = (1.0 * fb2_w / fb0_h) * h; |
510 | h1 = (1.0 * fb2_h / fb0_w) * w; |
511 | } |
512 | x = x1; |
513 | y = y1; |
514 | w = w1; |
515 | h = h1; |
516 | } else { |
517 | int x1, y1, w1, h1; |
518 | x1 = (1.0 * fb2_w / fb0_w) * x; |
519 | y1 = (1.0 * fb2_h / fb0_h) * y; |
520 | w1 = (1.0 * fb2_w / fb0_w) * w; |
521 | h1 = (1.0 * fb2_h / fb0_h) * h; |
522 | x = x1; |
523 | y = y1; |
524 | w = w1; |
525 | h = h1; |
526 | } |
527 | } |
528 | } |
529 | #ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 |
530 | if (screen_portrait && hdmi_swith_on_vpp1) { |
531 | int val = 0 ; |
532 | val = x ; |
533 | x = y; |
534 | y = val; |
535 | val = w; |
536 | w = h; |
537 | h = val; |
538 | } |
539 | #endif |
540 | LOGI("amvideo_utils_set_virtual_position :: x=%d y=%d w=%d h=%d\n", x, y, w, h); |
541 | |
542 | bzero(buf, SYSCMD_BUFSIZE); |
543 | |
544 | dst_x = x; |
545 | dst_y = y; |
546 | dst_w = w; |
547 | dst_h = h; |
548 | |
549 | if (amsysfs_get_sysfs_str(DISP_DEVICE_PATH, buf, sizeof(buf)) == 0) { |
550 | if (sscanf(buf, "%dx%d", &dev_w, &dev_h) == 2) { |
551 | LOGI("device resolution %dx%d\n", dev_w, dev_h); |
552 | } else { |
553 | ret = -2; |
554 | goto OUT; |
555 | } |
556 | } else { |
557 | goto OUT; |
558 | } |
559 | |
560 | |
561 | if (video_on_vpp2) { |
562 | amdisplay_utils_get_size_fb2(&disp_w, &disp_h); |
563 | } else { |
564 | amdisplay_utils_get_size(&disp_w, &disp_h); |
565 | } |
566 | |
567 | LOGI("amvideo_utils_set_virtual_position:: disp_w=%d, disp_h=%d\n", disp_w, disp_h); |
568 | |
569 | video_global_offset = amvideo_utils_get_global_offset(); |
570 | |
571 | int free_scale_enable = 0; |
572 | int ppscaler_enable = 0; |
573 | int freescale_mode_enable = 0; |
574 | |
575 | if (((disp_w != dev_w) || (disp_h / 2 != dev_h)) && |
576 | (video_global_offset == 0)) { |
577 | char val[256]; |
578 | char freescale_mode[50] = {0}; |
579 | char *p; |
580 | memset(val, 0, sizeof(val)); |
581 | if (video_on_vpp2) { |
582 | if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB2, val, sizeof(val)) == 0) { |
583 | /* the returned string should be "free_scale_enable:[0x%x]" */ |
584 | free_scale_enable = (val[21] == '0') ? 0 : 1; |
585 | } |
586 | } else if (hdmi_swith_on_vpp1) { |
587 | if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB1, val, sizeof(val)) == 0) { |
588 | /* the returned string should be "free_scale_enable:[0x%x]" */ |
589 | free_scale_enable = (val[21] == '0') ? 0 : 1; |
590 | } |
591 | } else { |
592 | if (amsysfs_get_sysfs_str(FREE_SCALE_PATH, val, sizeof(val)) == 0) { |
593 | /* the returned string should be "free_scale_enable:[0x%x]" */ |
594 | free_scale_enable = (val[21] == '0') ? 0 : 1; |
595 | } |
596 | } |
597 | |
598 | memset(val, 0, sizeof(val)); |
599 | if (amsysfs_get_sysfs_str(PPSCALER_PATH, val, sizeof(val)) == 0) { |
600 | /* the returned string should be "current ppscaler mode is disabled/enable" */ |
601 | ppscaler_enable = (val[25] == 'd') ? 0 : 1; |
602 | } |
603 | |
604 | memset(val, 0, sizeof(val)); |
605 | if (amsysfs_get_sysfs_str(FREE_SCALE_MODE_PATH, val, sizeof(val)) == 0) { |
606 | /* the returned string should be "free_scale_mode:new/default" */ |
607 | p = strstr(val, "current"); |
608 | if (p) { |
609 | strcpy(freescale_mode, p); |
610 | } else { |
611 | freescale_mode[0] = '\0'; |
612 | } |
613 | freescale_mode_enable = (strstr(freescale_mode, "0") == NULL) ? 1 : 0; |
614 | } |
615 | } |
616 | |
617 | #ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 |
618 | if ((video_on_vpp2 && vertical_panel) || (screen_portrait && video_on_vpp2_new) |
619 | || (screen_portrait && hdmi_swith_on_vpp1)) |
620 | #else |
621 | if ((video_on_vpp2 && vertical_panel) || (screen_portrait && video_on_vpp2_new) |
622 | /*||(screen_portrait && hdmi_swith_on_vpp1)*/) |
623 | #endif |
624 | amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, 0); |
625 | else { |
626 | amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, (rotation / 90) & 3); |
627 | } |
628 | |
629 | LOGI("set ppmgr angle :%d\n", (rotation / 90) & 3); |
630 | /* this is unlikely and only be used when ppmgr does not exist |
631 | * to support video rotation. If that happens, we convert the window |
632 | * position to non-rotated window position. |
633 | * On ICS, this might not work at all because the transparent UI |
634 | * window is still drawn is it's direction, just comment out this for now. |
635 | */ |
636 | #if 0 |
637 | if (((rotation == 90) || (rotation == 270)) && (angle_fd < 0)) { |
638 | if (dst_h == disp_h) { |
639 | int center = x + w / 2; |
640 | |
641 | if (abs(center - disp_w / 2) < 2) { |
642 | /* a centered overlay with rotation, change to full screen */ |
643 | dst_x = 0; |
644 | dst_y = 0; |
645 | dst_w = dev_w; |
646 | dst_h = dev_h; |
647 | |
648 | LOGI("centered overlay expansion"); |
649 | } |
650 | } |
651 | } |
652 | #endif |
653 | /*if (free_scale_enable == 0 && ppscaler_enable == 0) { |
654 | |
655 | OSD_DISP_MODE display_mode = OSD_DISP_1080P; |
656 | int x_d=0,y_d=0,w_d=0,h_d=0; |
657 | LOGI("set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); |
658 | |
659 | display_mode = get_osd_display_mode(); |
660 | get_device_win(display_mode, &x_d, &y_d, &w_d, &h_d); |
661 | if (display_mode == OSD_DISP_720P) { |
662 | if ((dst_w >= 1279) || (dst_w == 0)) { |
663 | dst_x = x_d; |
664 | dst_y = y_d; |
665 | dst_w = w_d; |
666 | dst_h = h_d; |
667 | } |
668 | else { |
669 | dst_x = dst_x*w_d/1280+x_d; |
670 | dst_y = dst_y*h_d/720+y_d; |
671 | dst_w = dst_w*w_d/1280; |
672 | dst_h = dst_h*h_d/720; |
673 | } |
674 | } |
675 | else if ((display_mode==OSD_DISP_1080I)||(display_mode==OSD_DISP_1080P)||(display_mode==OSD_DISP_LVDS1080P)) { |
676 | if ((dst_w >= 1919) || (dst_w == 0)) { |
677 | dst_x = x_d; |
678 | dst_y = y_d; |
679 | dst_w = w_d; |
680 | dst_h = h_d; |
681 | } |
682 | else {//scaled to 1080p |
683 | dst_x = dst_x*w_d/1920+x_d; |
684 | dst_y = dst_y*h_d/1080+y_d; |
685 | dst_w = dst_w*w_d/1920; |
686 | dst_h = dst_h*h_d/1080; |
687 | |
688 | LOGI("after scaled to 1080 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); |
689 | } |
690 | } |
691 | else if ((display_mode==OSD_DISP_480I)||(display_mode==OSD_DISP_480P)) { |
692 | if ((dst_w >= 719) || (dst_w == 0)) { |
693 | dst_x = x_d; |
694 | dst_y = y_d; |
695 | dst_w = w_d; |
696 | dst_h = h_d; |
697 | } |
698 | else {//scaled to 480p/480i |
699 | dst_x = dst_x*w_d/720+x_d; |
700 | dst_y = dst_y*h_d/480+y_d; |
701 | dst_w = dst_w*w_d/720; |
702 | dst_h = dst_h*h_d/480; |
703 | |
704 | LOGI("after scaled to 480,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); |
705 | } |
706 | } |
707 | else if ((display_mode==OSD_DISP_576I)||(display_mode==OSD_DISP_576P)) { |
708 | if ((dst_w >= 719) || (dst_w == 0)) { |
709 | dst_x = x_d; |
710 | dst_y = y_d; |
711 | dst_w = w_d; |
712 | dst_h = h_d; |
713 | } |
714 | else {//scaled to 576p/576i |
715 | dst_x = dst_x*w_d/720+x_d; |
716 | dst_y = dst_y*h_d/576+y_d; |
717 | dst_w = dst_w*w_d/720; |
718 | dst_h = dst_h*h_d/576; |
719 | |
720 | LOGI("after scaled to 576 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); |
721 | } |
722 | } |
723 | }*/ |
724 | |
725 | if (free_scale_enable == 0 && ppscaler_enable == 0) { |
726 | char val[256]; |
727 | char axis_string[100]; |
728 | char num[11]="0123456789\0"; |
729 | char *first_num, *last_num; |
730 | |
731 | if (freescale_mode_enable == 1) { |
732 | int left = 0, top = 0, right = 0, bottom = 0; |
733 | int x = 0, y = 0, w = 0, h = 0; |
734 | |
735 | memset(val, 0, sizeof(val)); |
736 | if (amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)) == 0 |
737 | && (is_panel_mode() == 0)) { |
738 | /* the returned string should be "window axis is [a b c d]" */ |
739 | first_num = strpbrk(val,num); |
740 | if (first_num != NULL) { |
741 | memset(axis_string, 0, sizeof(axis_string)); |
742 | strcpy(axis_string, first_num); |
743 | last_num = strchr(axis_string, ']'); |
744 | if (last_num) { |
745 | *last_num = '\0'; |
746 | } |
747 | } |
748 | if (sscanf(axis_string, "%d %d %d %d", &left, &top, &right, &bottom) == 4) { |
749 | if ((right > 0) && (bottom > 0)) { |
750 | x = left; |
751 | y = top; |
752 | w = right - left + 1; |
753 | h = bottom - top + 1; |
754 | |
755 | dst_x = dst_x * w / dev_w + x; |
756 | dst_y = dst_y * h / dev_h + y; |
757 | LOGI("after scaled, screen position1: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); |
758 | } |
759 | } |
760 | } |
761 | } else { |
762 | int x = 0, y = 0, w = 0, h = 0; |
763 | int fb_w = 0, fb_h = 0; |
764 | int req_2xscale = 0; |
765 | |
766 | memset(val, 0, sizeof(val)); |
767 | if (amsysfs_get_sysfs_str(PPSCALER_RECT, val, sizeof(val)) == 0) { |
768 | /* the returned string should be "a b c" */ |
769 | if (sscanf(val, "ppscaler rect:\nx:%d,y:%d,w:%d,h:%d", &x, &y, &w, &h) == 4) { |
770 | if ((w > 1) && (h > 1)) { |
771 | if (fb_w == 0 || fb_h == 0) { |
772 | fb_w = 1280; |
773 | fb_h = 720; |
774 | } |
775 | set_scale(x, y, w - 1, h - 1, &dst_x, &dst_y, &dst_w, &dst_h, fb_w, fb_h); |
776 | LOGI("after scaled, screen position2: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); |
777 | } |
778 | } |
779 | } |
780 | } |
781 | } else if (free_scale_enable == 1 && ppscaler_enable == 0) { |
782 | char val[256]; |
783 | char axis_string[100]; |
784 | char num[11]="0123456789\0"; |
785 | char *first_num, *last_num; |
786 | int left = 0, top = 0, right = 0, bottom = 0; |
787 | int x = 0, y = 0, w = 0, h = 0; |
788 | int freescale_x = 0, freescale_y = 0, freescale_w = 0, freescale_h = 0; |
789 | |
790 | int mGetWinAxis = 0; |
791 | if (hdmi_swith_on_vpp1) { |
792 | mGetWinAxis = amsysfs_get_sysfs_str(WINDOW_AXIS_PATH_FB1, val, sizeof(val)); |
793 | } else { |
794 | mGetWinAxis = amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)); |
795 | } |
796 | |
797 | if (mGetWinAxis == 0) { |
798 | /* the returned string should be "window axis is [a b c d]" */ |
799 | first_num = strpbrk(val,num); |
800 | if (first_num != NULL) { |
801 | memset(axis_string, 0, sizeof(axis_string)); |
802 | strcpy(axis_string, first_num); |
803 | last_num = strchr(axis_string, ']'); |
804 | if (last_num) { |
805 | *last_num = '\0'; |
806 | } |
807 | } |
808 | if (sscanf(axis_string, "%d %d %d %d", &left, &top, &right, &bottom) == 4) { |
809 | x = left; |
810 | y = top; |
811 | w = right - left + 1; |
812 | h = bottom - top + 1; |
813 | |
814 | if (hdmi_swith_on_vpp1) { |
815 | freescale_x = 0; |
816 | freescale_y = 0; |
817 | if (screen_portrait) { |
818 | freescale_w = disp_h; |
819 | freescale_h = disp_w; |
820 | } else { |
821 | freescale_w = disp_w; |
822 | freescale_h = disp_h; |
823 | } |
824 | } else { |
825 | get_axis(FREE_SCALE_AXIS_PATH, &freescale_x, &freescale_y, &freescale_w, &freescale_h); |
826 | } |
827 | freescale_w = (freescale_w + 1) & (~1); |
828 | freescale_h = (freescale_h + 1) & (~1); |
829 | |
830 | set_scale(x, y, w, h, &dst_x, &dst_y, &dst_w, &dst_h, freescale_w, freescale_h); |
831 | LOGI("after scaled, screen position3: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); |
832 | } |
833 | } |
834 | } |
835 | |
836 | axis[0] = dst_x; |
837 | axis[1] = dst_y; |
838 | axis[2] = dst_x + dst_w - 1; |
839 | axis[3] = dst_y + dst_h - 1; |
840 | sprintf(buf, "%d %d %d %d", axis[0], axis[1], axis[2], axis[3]); |
841 | amsysfs_set_sysfs_str(VIDEO_AXIS_PATH, buf); |
842 | |
843 | ret = 0; |
844 | OUT: |
845 | |
846 | LOGI("amvideo_utils_set_virtual_position (corrected):: x=%d y=%d w=%d h=%d\n", dst_x, dst_y, dst_w, dst_h); |
847 | amvideo_setscreenmode(); |
848 | |
849 | return ret; |
850 | } |
851 | |
852 | int amvideo_utils_set_absolute_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation) |
853 | { |
854 | LOG_FUNCTION_NAME |
855 | char buf[SYSCMD_BUFSIZE]; |
856 | int axis[4]; |
857 | int video_on_vpp2 = is_video_on_vpp2(); |
858 | int vertical_panel = is_vertical_panel(); |
859 | |
860 | LOGI("amvideo_utils_set_absolute_position:: x=%d y=%d w=%d h=%d\n", x, y, w, h); |
861 | |
862 | if ((video_on_vpp2 && vertical_panel)) { |
863 | amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, 0); |
864 | } else { |
865 | amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, (rotation / 90) & 3); |
866 | } |
867 | |
868 | axis[0] = x; |
869 | axis[1] = y; |
870 | axis[2] = x + w - 1; |
871 | axis[3] = y + h - 1; |
872 | |
873 | sprintf(buf, "%d %d %d %d", axis[0], axis[1], axis[2], axis[3]); |
874 | amsysfs_set_sysfs_str(VIDEO_AXIS_PATH, buf); |
875 | |
876 | return 0; |
877 | } |
878 | |
879 | int amvideo_utils_get_position(int32_t *x, int32_t *y, int32_t *w, int32_t *h) |
880 | { |
881 | LOG_FUNCTION_NAME |
882 | int axis[4]; |
883 | get_axis(VIDEO_AXIS_PATH, &axis[0], &axis[1], &axis[2], &axis[3]); |
884 | *x = axis[0]; |
885 | *y = axis[1]; |
886 | *w = axis[2] - axis[0] + 1; |
887 | *h = axis[3] - axis[1] + 1; |
888 | |
889 | return 0; |
890 | } |
891 | |
892 | int amvideo_utils_get_screen_mode(int *mode) |
893 | { |
894 | LOG_FUNCTION_NAME |
895 | int video_fd; |
896 | int screen_mode = 0; |
897 | |
898 | video_fd = open(VIDEO_PATH, O_RDWR); |
899 | if (video_fd < 0) { |
900 | return -1; |
901 | } |
902 | |
903 | ioctl(video_fd, AMSTREAM_IOC_GET_SCREEN_MODE, &screen_mode); |
904 | |
905 | close(video_fd); |
906 | |
907 | *mode = screen_mode; |
908 | |
909 | return 0; |
910 | } |
911 | |
912 | int amvideo_utils_set_screen_mode(int mode) |
913 | { |
914 | LOG_FUNCTION_NAME |
915 | int screen_mode = mode; |
916 | int video_fd; |
917 | |
918 | video_fd = open(VIDEO_PATH, O_RDWR); |
919 | if (video_fd < 0) { |
920 | return -1; |
921 | } |
922 | |
923 | ioctl(video_fd, AMSTREAM_IOC_SET_SCREEN_MODE, &screen_mode); |
924 | |
925 | close(video_fd); |
926 | |
927 | return 0; |
928 | } |
929 | |
930 | int amvideo_utils_get_video_angle(int *angle) |
931 | { |
932 | LOG_FUNCTION_NAME |
933 | char buf[SYSCMD_BUFSIZE]; |
934 | int angle_val; |
935 | if (amsysfs_get_sysfs_str(PPMGR_ANGLE_PATH, buf, sizeof(buf)) == 0) { |
936 | if (sscanf(buf, "current angel is %d", &angle_val) == 1) { |
937 | *angle = angle_val; |
938 | } |
939 | } |
940 | return 0; |
941 | } |
942 | |
943 | int amvideo_utils_get_hdmi_authenticate(void) |
944 | { |
945 | LOG_FUNCTION_NAME |
946 | int fd = -1; |
947 | int val = -1; |
948 | char bcmd[16]; |
949 | fd = open(HDMI_AUTHENTICATE_PATH, O_RDONLY); |
950 | if (fd >= 0) { |
951 | read(fd, bcmd, sizeof(bcmd)); |
952 | val = strtol(bcmd, NULL, 10); |
953 | close(fd); |
954 | } |
955 | return val; |
956 | } |
957 |