Beispiel #1
0
int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation)
{
    LOG_FUNCTION_NAME
	//for osd rotation, need convert the axis first
	int osd_rotation = amdisplay_utils_get_osd_rotation();
	if(osd_rotation > 0)
        amvideo_convert_axis(&x,&y,&w,&h,&rotation,osd_rotation);

    int video_fd;
    int dev_fd = -1, dev_w, dev_h, disp_w, disp_h, video_global_offset;
    int dst_x, dst_y, dst_w, dst_h;
    char buf[SYSCMD_BUFSIZE];
    int angle_fd = -1;
    int ret = -1;
    int axis[4];
    char enable_p2p_play[8] = {0};
    int video_on_vpp2 = is_video_on_vpp2();
    int vertical_panel = is_vertical_panel();
    int vertical_panel_reverse = is_vertical_panel_reverse();

    if (video_on_vpp2) {
        int fb0_w, fb0_h, fb2_w, fb2_h;

        amdisplay_utils_get_size(&fb0_w, &fb0_h);
        amdisplay_utils_get_size_fb2(&fb2_w, &fb2_h);

        if (fb0_w > 0 && fb0_h > 0 && fb2_w > 0 && fb2_h > 0) {
            if (vertical_panel) {
                int x1, y1, w1, h1;
                if (vertical_panel_reverse) {
                    x1 = (1.0 * fb2_w / fb0_h) * y;
                    y1 = (1.0 * fb2_h / fb0_w) * x;
                    w1 = (1.0 * fb2_w / fb0_h) * h;
                    h1 = (1.0 * fb2_h / fb0_w) * w;
                } else {
                    x1 = (1.0 * fb2_w / fb0_h) * y;
                    y1 = (1.0 * fb2_h / fb0_w) * (fb0_w - x - w);
                    w1 = (1.0 * fb2_w / fb0_h) * h;
                    h1 = (1.0 * fb2_h / fb0_w) * w;
                }
                x = x1;
                y = y1;
                w = w1;
                h = h1;
            } else {
                int x1, y1, w1, h1;
                x1 = (1.0 * fb2_w / fb0_w) * x;
                y1 = (1.0 * fb2_h / fb0_h) * y;
                w1 = (1.0 * fb2_w / fb0_w) * w;
                h1 = (1.0 * fb2_h / fb0_h) * h;
                x = x1;
                y = y1;
                w = w1;
                h = h1;
            }
        }
    }
    LOGI("amvideo_utils_set_virtual_position:: x=%d y=%d w=%d h=%d\n", x, y, w, h);

    bzero(buf, SYSCMD_BUFSIZE);

    dst_x = x;
    dst_y = y;
    dst_w = w;
    dst_h = h;

    video_fd = open(VIDEO_PATH, O_RDWR);
    if (video_fd < 0) {
        goto OUT;
    }

    dev_fd = open(DISP_DEVICE_PATH, O_RDONLY);
    if (dev_fd < 0) {
        goto OUT;
    }

    read(dev_fd, buf, SYSCMD_BUFSIZE);

    if (sscanf(buf, "%dx%d", &dev_w, &dev_h) == 2) {
        LOGI("device resolution %dx%d\n", dev_w, dev_h);
    } else {
        ret = -2;
        goto OUT;
    }

    if (video_on_vpp2)
        amdisplay_utils_get_size_fb2(&disp_w, &disp_h);
    else
        amdisplay_utils_get_size(&disp_w, &disp_h);

    LOGI("amvideo_utils_set_virtual_position:: disp_w=%d, disp_h=%d\n", disp_w, disp_h);

    video_global_offset = amvideo_utils_get_global_offset();

    int free_scale_enable = 0;
    int ppscaler_enable = 0;
    int freescale_mode_enable = 0;

    if (((disp_w != dev_w) || (disp_h / 2 != dev_h)) &&
        (video_global_offset == 0)) {
        char val[256];

        memset(val, 0, sizeof(val));
        if (video_on_vpp2) {
            if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB2, val, sizeof(val)) == 0) {
                /* the returned string should be "free_scale_enable:[0x%x]" */
                free_scale_enable = (val[21] == '0') ? 0 : 1;
            }
        } else {
            if (amsysfs_get_sysfs_str(FREE_SCALE_PATH, val, sizeof(val)) == 0) {
                /* the returned string should be "free_scale_enable:[0x%x]" */
                free_scale_enable = (val[21] == '0') ? 0 : 1;
            }
        }

        memset(val, 0, sizeof(val));
        if (amsysfs_get_sysfs_str(PPSCALER_PATH, val, sizeof(val)) == 0) {
            /* the returned string should be "current ppscaler mode is disabled/enable" */
            ppscaler_enable = (val[25] == 'd') ? 0 : 1;
        }

        memset(val, 0, sizeof(val));
        if (amsysfs_get_sysfs_str(FREE_SCALE_MODE_PATH, val, sizeof(val)) == 0) {
            /* the returned string should be "free_scale_mode:new/default" */
            freescale_mode_enable = (val[16] == 'd') ? 0 : 1;
        }
    }

    angle_fd = open(ANGLE_PATH, O_WRONLY);
    if (angle_fd >= 0) {
        if (video_on_vpp2 && vertical_panel)
            ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, 0);
        else
            ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, (rotation/90) & 3);
        LOGI("set ppmgr angle %d\n", (rotation/90) & 3);
    }

    /* this is unlikely and only be used when ppmgr does not exist
     * to support video rotation. If that happens, we convert the window
     * position to non-rotated window position.
     * On ICS, this might not work at all because the transparent UI
     * window is still drawn is it's direction, just comment out this for now.
     */
#if 0
    if (((rotation == 90) || (rotation == 270)) && (angle_fd < 0)) {
        if (dst_h == disp_h) {
            int center = x + w / 2;

            if (abs(center - disp_w / 2) < 2) {
                /* a centered overlay with rotation, change to full screen */
                dst_x = 0;
                dst_y = 0;
                dst_w = dev_w;
                dst_h = dev_h;

                LOGI("centered overlay expansion");
            }
        }
    }
#endif
    /*if (free_scale_enable == 0 && ppscaler_enable == 0) {

        OSD_DISP_MODE display_mode = OSD_DISP_1080P;
        int x_d=0,y_d=0,w_d=0,h_d=0;
        LOGI("set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h);

        display_mode = get_osd_display_mode();
        get_device_win(display_mode, &x_d, &y_d, &w_d, &h_d);
        if(display_mode==OSD_DISP_720P) {
            if((dst_w >= 1279)||(dst_w==0)) {
                dst_x = x_d;
                dst_y = y_d;
                dst_w = w_d;
                dst_h = h_d;
            }
            else {
                dst_x = dst_x*w_d/1280+x_d;
                dst_y = dst_y*h_d/720+y_d;
                dst_w = dst_w*w_d/1280;
                dst_h = dst_h*h_d/720;
            }
        }
        else if((display_mode==OSD_DISP_1080I)||(display_mode==OSD_DISP_1080P)||(display_mode==OSD_DISP_LVDS1080P)) {
            if((dst_w >= 1919)||(dst_w == 0)) {
                dst_x = x_d;
                dst_y = y_d;
                dst_w = w_d;
                dst_h = h_d;
            }
            else {//scaled to 1080p
                dst_x = dst_x*w_d/1920+x_d;
                dst_y = dst_y*h_d/1080+y_d;
                dst_w = dst_w*w_d/1920;
                dst_h = dst_h*h_d/1080;

                LOGI("after scaled to 1080 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h);
            }
        }
        else if((display_mode==OSD_DISP_480I)||(display_mode==OSD_DISP_480P)) {
            if((dst_w >= 719)||(dst_w == 0)) {
                dst_x = x_d;
                dst_y = y_d;
                dst_w = w_d;
                dst_h = h_d;
            }
            else {//scaled to 480p/480i
                dst_x = dst_x*w_d/720+x_d;
                dst_y = dst_y*h_d/480+y_d;
                dst_w = dst_w*w_d/720;
                dst_h = dst_h*h_d/480;

                LOGI("after scaled to 480,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h);
            }
        }
        else if((display_mode==OSD_DISP_576I)||(display_mode==OSD_DISP_576P)) {
            if((dst_w >= 719)||(dst_w == 0)) {
                dst_x = x_d;
                dst_y = y_d;
                dst_w = w_d;
                dst_h = h_d;
            }
            else {//scaled to 576p/576i
                dst_x = dst_x*w_d/720+x_d;
                dst_y = dst_y*h_d/576+y_d;
                dst_w = dst_w*w_d/720;
                dst_h = dst_h*h_d/576;

                LOGI("after scaled to 576 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h);
            }
        }
    }*/
    if (free_scale_enable == 0 && ppscaler_enable == 0) {
        char val[256];

        if (freescale_mode_enable == 1) {
            int left = 0, top = 0, right = 0, bottom = 0;
            int x = 0, y = 0, w = 0, h = 0;

            memset(val, 0, sizeof(val));
            if (amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)) == 0) {
                /* the returned string should be "window axis is [a b c d]" */
                if (sscanf(val + 15, "[%d %d %d %d]", &left, &top, &right, &bottom) == 4) {
                    x = left;
                    y = top;
                    w = right - left + 1;
                    h = bottom - top + 1;
                    if ((dst_w >= dev_w - 1) || (dst_w == 0)) {
                        dst_x = 0;
                        dst_w = w;
                    }
                    if ((dst_h >= dev_h - 1) || (dst_h == 0)) {
                        dst_y = 0;
                        dst_h = h;
                    }

                    dst_x = dst_x * w / dev_w + x;
                    dst_y = dst_y * h / dev_h + y;
                    LOGI("after scaled, screen position: %d %d %d %d", dst_x, dst_y, dst_w, dst_h);
                }
            }
        } else {
            int x = 0, y = 0, w = 0, h = 0;
            int fb_w = 0, fb_h = 0;
            int req_2xscale = 0;

            memset(val, 0, sizeof(val));
            if (amsysfs_get_sysfs_str(REQUEST_2XSCALE_PATH, val, sizeof(val)) == 0) {
                /* the returned string should be "a b c" */
                if (sscanf(val, "%d", &req_2xscale) == 1) {
                    if (req_2xscale == 7 || req_2xscale == 16) {
                        if (sscanf(val, "%d %d %d", &req_2xscale, &w, &h) == 3) {
                            if (req_2xscale == 7)
                                w *= 2;
                            get_axis(DISPLAY_AXIS_PATH, &x, &y, &fb_w, &fb_h);
                            if (fb_w == 0 || fb_h == 0) {
                                fb_w = 1280;
                                fb_h = 720;
                            }
                            set_scale(x, y, w, h, &dst_x, &dst_y, &dst_w, &dst_h, fb_w, fb_h);
                            LOGI("after scaled, screen position: %d %d %d %d", dst_x, dst_y, dst_w, dst_h);
                        }
                    }
                }
            }
        }
    } else if (free_scale_enable == 1 && ppscaler_enable == 0) {
        char val[256];
        int left = 0, top = 0, right = 0, bottom = 0;
        int x = 0, y = 0, w = 0, h = 0;
        int freescale_x = 0, freescale_y = 0, freescale_w = 0, freescale_h = 0;

        if (amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)) == 0) {
            /* the returned string should be "window axis is [a b c d]" */
            if (sscanf(val + 15, "[%d %d %d %d]", &left, &top, &right, &bottom) == 4) {
                x = left;
                y = top;
                w = right - left + 1;
                h = bottom - top + 1;

                get_axis(FREE_SCALE_AXIS_PATH, &freescale_x, &freescale_y, &freescale_w, &freescale_h);
                freescale_w = (freescale_w + 1) & (~1);
                freescale_h = (freescale_h + 1) & (~1);

                set_scale(x, y, w, h, &dst_x, &dst_y, &dst_w, &dst_h, freescale_w, freescale_h);
                LOGI("after scaled, screen position: %d %d %d %d", dst_x, dst_y, dst_w, dst_h);
            }
        }
    }

    axis[0] = dst_x;
    axis[1] = dst_y;
    axis[2] = dst_x + dst_w - 1;
    axis[3] = dst_y + dst_h - 1;

    ioctl(video_fd, AMSTREAM_IOC_SET_VIDEO_AXIS, &axis[0]);

    ret = 0;
OUT:
    if (video_fd >= 0) {
        close(video_fd);
    }

    if (dev_fd >= 0) {
        close(dev_fd);
    }

    if (angle_fd >= 0) {
        close(angle_fd);
    }
    LOGI("amvideo_utils_set_virtual_position (corrected):: x=%d y=%d w=%d h=%d\n", dst_x, dst_y, dst_w, dst_h);

    return ret;
}
int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation)
{
    LOG_FUNCTION_NAME
    int video_fd;
    int dev_fd = -1, dev_w, dev_h, disp_w, disp_h, video_global_offset;
    int dst_x, dst_y, dst_w, dst_h;
    char buf[SYSCMD_BUFSIZE];
    int angle_fd = -1;
    int ret = -1;
    int axis[4];

    int video_on_vpp2 = is_video_on_vpp2();
    int vertical_panel = is_vertical_panel();
    
    if (video_on_vpp2) {
        int fb0_w, fb0_h, fb2_w, fb2_h;
        
        amdisplay_utils_get_size(&fb0_w, &fb0_h);
        amdisplay_utils_get_size_fb2(&fb2_w, &fb2_h);
        
        if (fb0_w > 0 && fb0_h > 0 && fb2_w > 0 && fb2_h > 0) {
            if (vertical_panel) {
                int x1, y1, w1, h1;
                x1 = (1.0 * fb2_w / fb0_h) * y;
                y1 = (1.0 * fb2_h / fb0_w) * (fb0_w - x - w);
                w1 = (1.0 * fb2_w / fb0_h) * h;
                h1 = (1.0 * fb2_h / fb0_w) * w;
                x = x1;
                y = y1;
                w = w1;
                h = h1;
            } else {
                int x1, y1, w1, h1;
                x1 = (1.0 * fb2_w / fb0_w) * x;
                y1 = (1.0 * fb2_h / fb0_h) * y;
                w1 = (1.0 * fb2_w / fb0_w) * w;
                h1 = (1.0 * fb2_h / fb0_h) * h;            
                x = x1;
                y = y1;
                w = w1;
                h = h1;        
            }
        }        
    }
    LOGI("amvideo_utils_set_virtual_position:: x=%d y=%d w=%d h=%d\n", x, y, w, h);

    bzero(buf, SYSCMD_BUFSIZE);

    dst_x = x;
    dst_y = y;
    dst_w = w;
    dst_h = h;

    video_fd = open(VIDEO_PATH, O_RDWR);
    if (video_fd < 0) {
        goto OUT;
    }

    dev_fd = open(DISP_DEVICE_PATH, O_RDONLY);
    if (dev_fd < 0) {
        goto OUT;
    }

    read(dev_fd, buf, SYSCMD_BUFSIZE);

    if (sscanf(buf, "%dx%d", &dev_w, &dev_h) == 2) {
        LOGI("device resolution %dx%d\n", dev_w, dev_h);
    } else {
        ret = -2;
        goto OUT;
    }

    if (video_on_vpp2)
        amdisplay_utils_get_size_fb2(&disp_w, &disp_h);
    else
        amdisplay_utils_get_size(&disp_w, &disp_h);
    LOGI("amvideo_utils_set_virtual_position:: disp_w=%d, disp_h=%d\n", disp_w, disp_h);    
        
    video_global_offset = amvideo_utils_get_global_offset();

    /* if we are doing video output to a second display device with
     * a different resolution, scale all the numbers.
     * E.g. when a MID pad is connected to a HDMI output.
     */
    if (((disp_w != dev_w) || (disp_h / 2 != dev_h)) &&
        (video_global_offset == 0)) {
        char val[256];
        int free_scale_enable = 0;
        int ppscaler_enable = 0;

        memset(val, 0, sizeof(val));
        if (video_on_vpp2) {
            if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB2, val, sizeof(val)) == 0) {
                /* the returned string should be "free_scale_enable:[0x%x]" */
                free_scale_enable = (val[21] == '0') ? 0 : 1;
            }
        } else {
            if (amsysfs_get_sysfs_str(FREE_SCALE_PATH, val, sizeof(val)) == 0) {
                /* the returned string should be "free_scale_enable:[0x%x]" */
                free_scale_enable = (val[21] == '0') ? 0 : 1;
            }            
        }

        memset(val, 0, sizeof(val));
        if (amsysfs_get_sysfs_str(PPSCALER_PATH, val, sizeof(val)) == 0) {
            /* the returned string should be "current ppscaler mode is disabled/enable" */            
            ppscaler_enable = (val[24] == 'd') ? 0 : 1;
        }

        if (free_scale_enable == 0 && ppscaler_enable == 0) {
            dst_x = dst_x * dev_w / disp_w;
            dst_y = dst_y * dev_h / disp_h;
            dst_w = dst_w * dev_w / disp_w;
            dst_h = dst_h * dev_h / disp_h;
        }
    }

    angle_fd = open(ANGLE_PATH, O_WRONLY);
    if (angle_fd >= 0) {
        if (video_on_vpp2 && vertical_panel)
            ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, 0);
        else
            ioctl(angle_fd, PPMGR_IOC_SET_ANGLE, (rotation/90) & 3);
        LOGI("set ppmgr angle %d\n", (rotation/90) & 3);
    }

    /* this is unlikely and only be used when ppmgr does not exist
     * to support video rotation. If that happens, we convert the window
     * position to non-rotated window position.
     * On ICS, this might not work at all because the transparent UI
     * window is still drawn is it's direction, just comment out this for now.
     */
#if 0
    if (((rotation == 90) || (rotation == 270)) && (angle_fd < 0)) {
        if (dst_h == disp_h) {
            int center = x + w / 2;

            if (abs(center - disp_w / 2) < 2) {
                /* a centered overlay with rotation, change to full screen */
                dst_x = 0;
                dst_y = 0;
                dst_w = dev_w;
                dst_h = dev_h;

                LOGI("centered overlay expansion");
            }
        }
    }
#endif

    axis[0] = dst_x;
    axis[1] = dst_y;
    axis[2] = dst_x + dst_w - 1;
    axis[3] = dst_y + dst_h - 1;
    
    ioctl(video_fd, AMSTREAM_IOC_SET_VIDEO_AXIS, &axis[0]);

    ret = 0;
OUT:
    if (video_fd >= 0) {
        close(video_fd);
    }
    
    if (dev_fd >= 0) {
        close(dev_fd);
    }
    
    if (angle_fd >= 0) {
        close(angle_fd);
    }
    LOGI("amvideo_utils_set_virtual_position (corrected):: x=%d y=%d w=%d h=%d\n", dst_x, dst_y, dst_w, dst_h);

    return ret;
}