Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the
      6  * "Software"), to deal in the Software without restriction, including
      7  * without limitation the rights to use, copy, modify, merge, publish,
      8  * distribute, sub license, and/or sell copies of the Software, and to
      9  * permit persons to whom the Software is furnished to do so, subject to
     10  * the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the
     13  * next paragraph) shall be included in all copies or substantial portions
     14  * of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Zhaohan Ren  <zhaohan.ren (at) intel.com>
     26  *    Shengquan Yuan  <shengquan.yuan (at) intel.com>
     27  *    Jiang Fei <jiang.fei (at) intel.com>
     28  *    Binglin Chen <binglin.chen (at) intel.com>
     29  *
     30  */
     31 #include <va/va_backend.h>
     32 #include "psb_output.h"
     33 #include "psb_surface.h"
     34 #include "psb_buffer.h"
     35 #include "psb_overlay.h"
     36 #include "psb_texture.h"
     37 #include <stdio.h>
     38 #include <string.h>
     39 #include <stdarg.h>
     40 #include "psb_android_glue.h"
     41 #include "psb_output_android.h"
     42 #ifndef BAYTRAIL
     43 #include "psb_HDMIExtMode.h"
     44 #endif
     45 #include "pnw_rotate.h"
     46 #include "psb_drv_debug.h"
     47 #include <wsbm/wsbm_manager.h>
     48 #include <hardware.h>
     49 
     50 #define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
     51 #define INIT_OUTPUT_PRIV    psb_android_output_p output = (psb_android_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv)
     52 
     53 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
     54 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
     55 #define IMAGE(id)  ((object_image_p) object_heap_lookup( &driver_data->image_heap, id ))
     56 #define SUBPIC(id)  ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id ))
     57 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
     58 
     59 #define GET_SURFACE_INFO_rotate(psb_surface) ((int) psb_surface->extra_info[5])
     60 #define GET_SURFACE_INFO_protect(psb_surface) ((int) psb_surface->extra_info[6])
     61 #define MAX_OVERLAY_IDLE_FRAME 4
     62 
     63 enum {
     64     eWidiOff             = 1,
     65     eWidiClone           = 2,
     66     eWidiExtendedVideo   = 3,
     67 };
     68 extern unsigned int update_forced;
     69 
     70 inline int va2hw_rotation(int va_rotate)
     71 {
     72     switch (va_rotate) {
     73     case VA_ROTATION_90:
     74         return HAL_TRANSFORM_ROT_270;
     75     case VA_ROTATION_180:
     76         return HAL_TRANSFORM_ROT_180;
     77     case VA_ROTATION_270:
     78         return HAL_TRANSFORM_ROT_90;
     79     defaut:
     80         return 0;
     81     }
     82 
     83     return 0;
     84 }
     85 
     86 unsigned char *psb_android_output_init(VADriverContextP ctx)
     87 {
     88     INIT_DRIVER_DATA;
     89     char put_surface[1024];
     90     psb_android_output_p output = calloc(1, sizeof(psb_android_output_s));
     91     struct fb_var_screeninfo vinfo;
     92     int fbfd = -1;
     93 
     94     if (output == NULL) {
     95         drv_debug_msg(VIDEO_DEBUG_ERROR, "Can't malloc memory\n");
     96         return NULL;
     97     }
     98     memset(output, 0, sizeof(psb_android_output_s));
     99 
    100     /* Guess the screen size */
    101     output->screen_width = 800;
    102     output->screen_height = 480;
    103 
    104     // Open the frame buffer for reading
    105     memset(&vinfo, 0, sizeof(vinfo));
    106     fbfd = open("/dev/graphics/fb0", O_RDONLY);
    107     if (fbfd) {
    108         if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
    109             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Error reading screen information.\n");
    110     }
    111     close(fbfd);
    112     output->screen_width = vinfo.xres;
    113     output->screen_height = vinfo.yres;
    114 
    115     /* TS by default */
    116     driver_data->output_method = PSB_PUTSURFACE_OVERLAY;
    117     driver_data->color_key = 0x000001; /*light blue*/
    118 
    119     if (psb_parse_config("PSB_VIDEO_CTEXTURES", &put_surface[0]) == 0) {
    120         drv_debug_msg(VIDEO_DEBUG_GENERAL, "PSB_VIDEO_CTEXTURES is enabled for vaPutSurfaceBuf\n");
    121         driver_data->ctexture = 1; /* Init CTEXTURE for vaPutSurfaceBuf */
    122     }
    123 
    124     if (psb_parse_config("PSB_VIDEO_COVERLAY", &put_surface[0]) == 0) {
    125         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Putsurface use client overlay\n");
    126         driver_data->output_method = PSB_PUTSURFACE_FORCE_COVERLAY;
    127     }
    128 
    129     driver_data->coverlay = 1;
    130 
    131     return (unsigned char *)output;
    132 }
    133 
    134 VAStatus psb_android_output_deinit(VADriverContextP ctx)
    135 {
    136     INIT_DRIVER_DATA;
    137     INIT_OUTPUT_PRIV;
    138     //psb_android_output_p output = GET_OUTPUT_DATA(ctx);
    139 #ifdef TARGET_HAS_MULTIPLE_DISPLAY
    140     if (output->mds != NULL) {
    141         deinit_mds_listener(output);
    142     }
    143 #endif
    144     return VA_STATUS_SUCCESS;
    145 }
    146 
    147 #ifndef BAYTRAIL
    148 static VAStatus psb_putsurface_ctexture(
    149     VADriverContextP ctx,
    150     VASurfaceID surface,
    151     unsigned char* data,
    152     short srcx,
    153     short srcy,
    154     unsigned short srcw,
    155     unsigned short srch,
    156     short destx,
    157     short desty,
    158     unsigned short destw,
    159     unsigned short desth,
    160     unsigned int __maybe_unused flags /* de-interlacing flags */
    161 )
    162 {
    163     INIT_DRIVER_DATA;
    164     INIT_OUTPUT_PRIV;
    165     object_surface_p obj_surface;
    166     int offset = 0;
    167     psb_surface_p psb_surface;
    168     VAStatus vaStatus = VA_STATUS_SUCCESS;
    169 
    170     obj_surface = SURFACE(surface);
    171     CHECK_SURFACE(obj_surface);
    172     psb_surface = obj_surface->psb_surface;
    173 
    174     //    psb_surface->buf.drm_buf;
    175     //    psb_surface->buf.pl_flags;
    176     psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch,
    177                                destx, desty, destw, desth, 0, /* no subtitle */
    178                                obj_surface->width, obj_surface->height,
    179                                psb_surface->stride, psb_surface->buf.drm_buf,
    180                                psb_surface->buf.pl_flags, 1 /* need wrap dst */);
    181 
    182     psb_android_postBuffer(offset);
    183 
    184     return VA_STATUS_SUCCESS;
    185 }
    186 #endif
    187 
    188 #if 0
    189 VAStatus psb_putsurface_coverlay(
    190     VADriverContextP ctx,
    191     VASurfaceID surface,
    192     short srcx,
    193     short srcy,
    194     unsigned short srcw,
    195     unsigned short srch,
    196     short destx, /* screen cooridination */
    197     short desty,
    198     unsigned short destw,
    199     unsigned short desth,
    200     unsigned int flags /* de-interlacing flags */
    201 )
    202 {
    203     INIT_OUTPUT_PRIV;
    204     VAStatus vaStatus = VA_STATUS_SUCCESS;
    205 
    206     /* USE_FIT_SCR_SIZE */
    207     /* calculate fit screen size of frame */
    208     unsigned short _scr_x = output->screen_width;
    209     unsigned short _scr_y = output->screen_height;
    210     float _slope_xy = (float)srch / srcw;
    211     unsigned short _destw = (short)(_scr_y / _slope_xy);
    212     unsigned short _desth = (short)(_scr_x * _slope_xy);
    213     short _pos_x, _pos_y;
    214 
    215     if (_destw <= _scr_x) {
    216         _desth = _scr_y;
    217         _pos_x = (_scr_x - _destw) >> 1;
    218         _pos_y = 0;
    219     } else {
    220         _destw = _scr_x;
    221         _pos_x = 0;
    222         _pos_y = (_scr_y - _desth) >> 1;
    223     }
    224     destx += _pos_x;
    225     desty += _pos_y;
    226     destw = _destw;
    227     desth = _desth;
    228 
    229     drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_overlay: src (%d, %d, %d, %d), destx (%d, %d, %d, %d).\n",
    230                              srcx, srcy, srcw, srch, destx, desty, destw, desth);
    231     /* display by overlay */
    232     vaStatus = psb_putsurface_overlay(
    233                    ctx, surface, srcx, srcy, srcw, srch,
    234                    destx, desty, destw, desth, /* screen coordinate */
    235                    flags, OVERLAY_A, PIPEA);
    236 
    237     return vaStatus;
    238 }
    239 #endif
    240 
    241 #if 0
    242 static int psb_update_destbox(
    243     VADriverContextP ctx
    244 )
    245 {
    246     INIT_DRIVER_DATA;
    247     INIT_OUTPUT_PRIV;
    248     short destx;
    249     short desty;
    250     unsigned short destw;
    251     unsigned short desth;
    252     VAStatus vaStatus = VA_STATUS_SUCCESS;
    253 
    254     psb_android_get_destbox(&destx, &desty, &destw, &desth);
    255     /*drv_debug_msg(VIDEO_DEBUG_GENERAL, "destbox = (%d,%d,%d,%d)\n", destx, desty, destw, desth);*/
    256     if ((destx >= 0) && (desty >= 0) &&
    257         ((destx + destw) <= output->screen_width) &&
    258         ((desty + desth) <= output->screen_height) &&
    259         (output->destx != destx ||
    260          output->desty != desty ||
    261          output->destw != destw ||
    262          output->desth != desth)) {
    263         output->destx = destx;
    264         output->desty = desty;
    265         output->destw = destw;
    266         output->desth = desth;
    267         output->new_destbox = 1;
    268 
    269         LOGD("==========New Destbox=============\n");
    270         LOGD("output->destbox = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth);
    271     }
    272 
    273     return vaStatus;
    274 }
    275 #endif
    276 
    277 #if 0
    278 static int psb_check_outputmethod(
    279     VADriverContextP ctx,
    280     VASurfaceID surface,
    281     unsigned short srcw,
    282     unsigned short srch,
    283     void *android_isurface,
    284     psb_hdmi_mode *hdmi_mode
    285 )
    286 {
    287     INIT_DRIVER_DATA;
    288     INIT_OUTPUT_PRIV;
    289     psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info;
    290     object_surface_p obj_surface;
    291     int rotation = 0, widi = 0;
    292     int delta_rotation = 0;
    293     int srf_rotate; /* primary surface rotation */
    294     psb_surface_p rotate_surface; /* rotate surface */
    295     int rotate_srf_rotate = -1; /* degree of the rotate surface */
    296 
    297     if ((srcw >= 2048) || (srch >= 2048)) {
    298         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Clip size extend overlay hw limit, use texstreaming\n");
    299         driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
    300         return 0;
    301     }
    302 
    303     /* use saved status to avoid per-frame checking */
    304     if ((driver_data->frame_count % driver_data->outputmethod_checkinterval) != 0) {
    305         *hdmi_mode = psb_HDMIExt_get_mode(output);
    306         return 0;
    307     }
    308 
    309     /* check the status at outputmethod_checkinterval frequency */
    310     /* at first check HDMI status */
    311     if (psb_HDMIExt_update(ctx, psb_HDMIExt_info)) {
    312         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to update HDMIExt info.\n", __FUNCTION__);
    313         return -1;
    314     }
    315 
    316     obj_surface = SURFACE(surface);
    317     if (obj_surface == NULL) {
    318         drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid surface\n");
    319         return -1;
    320     }
    321 
    322     *hdmi_mode = psb_HDMIExt_get_mode(output);
    323     if ((*hdmi_mode == EXTENDED_VIDEO) || (*hdmi_mode == CLONE)) {
    324         unsigned short _destw, _desth;
    325         short _pos_x, _pos_y;
    326         unsigned short crtc_width = 0, crtc_height = 0;
    327         float _slope_xy;
    328 
    329         /* need to handle VA rotation, and set WM rotate to 0
    330          * for Android, MIPI0/HDMI has the same WM rotation always
    331          */
    332         if (driver_data->mipi0_rotation != 0 || driver_data->rotation_dirty != 0) {
    333             driver_data->mipi0_rotation = 0;
    334             driver_data->hdmi_rotation = 0;
    335             driver_data->rotation_dirty = 0;
    336             output->new_destbox = 1;
    337             psb_RecalcRotate(ctx, CONTEXT(obj_surface->context_id));
    338         }
    339 
    340         psb_HDMIExt_get_prop(output, &crtc_width, &crtc_height);
    341 
    342         /*recalculate the render box to fit the ratio of height/width*/
    343         if ((driver_data->extend_rotation == VA_ROTATION_90) ||
    344             (driver_data->extend_rotation == VA_ROTATION_270))
    345             _slope_xy = (float)srcw / srch;
    346         else
    347             _slope_xy = (float)srch / srcw;
    348 
    349         _destw = (short)(crtc_height / _slope_xy);
    350         _desth = (short)(crtc_width * _slope_xy);
    351         if (_destw <= crtc_width) {
    352             _desth = crtc_height;
    353             _pos_x = (crtc_width - _destw) >> 1;
    354             _pos_y = 0;
    355         } else {
    356             _destw = crtc_width;
    357             _pos_x = 0;
    358             _pos_y = (crtc_height - _desth) >> 1;
    359         }
    360         driver_data->render_rect.x = _pos_x;
    361         driver_data->render_rect.y = _pos_y;
    362         driver_data->render_rect.width = _destw;
    363         driver_data->render_rect.height = _desth;
    364         drv_debug_msg(VIDEO_DEBUG_GENERAL, "HDMI mode is on (%d), Render Rect: (%d,%d,%d,%d)\n",
    365                                  *hdmi_mode,
    366                                  driver_data->render_rect.x, driver_data->render_rect.y,
    367                                  driver_data->render_rect.width, driver_data->render_rect.height);
    368         return 0;
    369     }
    370 
    371     /* HDMI is not enabled */
    372     psb_android_surfaceflinger_status(android_isurface, &output->sf_composition, &rotation, &widi);
    373     /*Update output destbox using layerbuffer's visible region*/
    374     psb_update_destbox(ctx);
    375 
    376     if ((driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY)
    377         || (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING))
    378         return 0;
    379 
    380     /*If overlay can not get correct destbox, use texstreaming.*/
    381     if (output->destw == 0 || output->desth == 0 ||
    382         ((output->destw == srcw) && (output->desth == srch))) {
    383         drv_debug_msg(VIDEO_DEBUG_GENERAL, "No proper destbox, use texstreaming (%dx%d+%d+%d)\n",
    384                                  output->destw, output->desth, output->destx, output->desty);
    385         driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
    386         return 0;
    387     }
    388 
    389     /* only care local rotation */
    390     delta_rotation = Rotation2Angle(driver_data->mipi0_rotation) - Rotation2Angle(rotation);
    391     if ((((abs(delta_rotation) == 90) || (abs(delta_rotation) == 270)) && output->new_destbox) ||
    392         (abs(delta_rotation) == 180)) {
    393         drv_debug_msg(VIDEO_DEBUG_GENERAL, "New rotation degree %d of MIPI0 WM, Need to recalc rotation\n", rotation);
    394         driver_data->mipi0_rotation = rotation;
    395         driver_data->hdmi_rotation = rotation;
    396         driver_data->rotation_dirty |= PSB_NEW_WM_ROTATION;
    397     }
    398     output->new_destbox = 0;
    399 
    400     if (driver_data->rotation_dirty != 0) {
    401         psb_RecalcRotate(ctx, CONTEXT(obj_surface->context_id));
    402         driver_data->rotation_dirty = 0;
    403     }
    404 
    405     if (GET_SURFACE_INFO_protect(obj_surface->psb_surface)) {
    406         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Protected surface, use overlay\n");
    407         driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
    408 
    409         return 0;
    410     }
    411 
    412     if (widi == eWidiClone) {
    413         drv_debug_msg(VIDEO_DEBUG_GENERAL, "WIDI in clone mode, use texstreaming\n");
    414         driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
    415         driver_data->msvdx_rotate_want = 0;/* disable msvdx rotae */
    416 
    417         return 0;
    418     }
    419     if (widi == eWidiExtendedVideo) {
    420         drv_debug_msg(VIDEO_DEBUG_GENERAL, "WIDI in extend video mode, disable local displaying\n");
    421         driver_data->output_method = PSB_PUTSURFACE_NONE;
    422         driver_data->msvdx_rotate_want = 0;/* disable msvdx rotae */
    423 
    424         return 0;
    425     }
    426 
    427     if (output->sf_composition) {
    428         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Composition is detected, use texstreaming\n");
    429         driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
    430         return 0;
    431     }
    432 
    433     srf_rotate = GET_SURFACE_INFO_rotate(obj_surface->psb_surface);
    434     rotate_surface = obj_surface->out_loop_surface;
    435     if (rotate_surface != NULL)
    436         rotate_srf_rotate = GET_SURFACE_INFO_rotate(rotate_surface);
    437 
    438     drv_debug_msg(VIDEO_DEBUG_GENERAL, "SF rotation %d, VA rotation %d, final MSVDX rotation %d\n",
    439                              rotation, driver_data->va_rotate, driver_data->local_rotation);
    440     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Primary surface rotation %d, rotated surface rotation %d\n",
    441                              srf_rotate, rotate_srf_rotate);
    442 
    443     /* The surface rotation is not same with the final rotation */
    444     if ((driver_data->local_rotation != 0) &&
    445         ((srf_rotate != driver_data->local_rotation) || (rotate_srf_rotate != driver_data->local_rotation))) {
    446         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Use texstreaming due to different VA surface rotation and final rotaion\n",
    447                                  srf_rotate, rotate_srf_rotate);
    448         driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
    449         return 0;
    450     }
    451 
    452     driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
    453 
    454     return 0;
    455 }
    456 #endif
    457 
    458 VAStatus psb_PutSurface(
    459     VADriverContextP ctx,
    460     VASurfaceID surface,
    461     void __maybe_unused * android_isurface,
    462     short srcx,
    463     short srcy,
    464     unsigned short srcw,
    465     unsigned short srch,
    466     short destx,
    467     short desty,
    468     unsigned short destw,
    469     unsigned short desth,
    470     VARectangle *cliprects, /* client supplied clip list */
    471     unsigned int number_cliprects, /* number of clip rects in the clip list */
    472     unsigned int flags /* de-interlacing flags */
    473 )
    474 {
    475     INIT_DRIVER_DATA;
    476     INIT_OUTPUT_PRIV;
    477     object_surface_p obj_surface;
    478     VAStatus vaStatus = VA_STATUS_SUCCESS;
    479     PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv);
    480     int ret = 0;
    481 
    482 #ifndef BAYTRAIL
    483 
    484     obj_surface = SURFACE(surface);
    485 
    486 //    psb__dump_NV_buffers(obj_surface,srcx,srcy,srcw,srch);
    487     CHECK_SURFACE(obj_surface);
    488     CHECK_INVALID_PARAM((NULL == cliprects) && (0 != number_cliprects));
    489 
    490     if ((srcx < 0) || (srcx > obj_surface->width) || (srcw > (obj_surface->width - srcx)) ||
    491         (srcy < 0) || (srcy > obj_surface->height_origin) || (srch > (obj_surface->height_origin - srcy))) {
    492         drv_debug_msg(VIDEO_DEBUG_ERROR, "vaPutSurface: source rectangle passed from upper layer is not correct.\n");
    493         return VA_STATUS_ERROR_UNKNOWN;
    494     }
    495     if ((destx < 0) || (desty < 0)) {
    496         drv_debug_msg(VIDEO_DEBUG_ERROR, "vaPutSurface: dest rectangle passed from upper layer is not correct.\n");
    497         return VA_STATUS_ERROR_UNKNOWN;
    498     }
    499 
    500     if (driver_data->dummy_putsurface) {
    501         drv_debug_msg(VIDEO_DEBUG_GENERAL, "vaPutSurface: dummy mode, return directly\n");
    502         return VA_STATUS_SUCCESS;
    503     }
    504 
    505     /* init overlay */
    506     if (!driver_data->coverlay_init) {
    507         ret = psb_coverlay_init(ctx);
    508         if (ret != 0) {
    509             drv_debug_msg(VIDEO_DEBUG_GENERAL, "vaPutSurface: psb_coverlay_init failed. Fallback to texture streaming.\n");
    510             driver_data->coverlay_init = 0;
    511         } else
    512             driver_data->coverlay_init = 1;
    513     }
    514 
    515     /* set the current displaying video frame into kernel */
    516     psb_surface_set_displaying(driver_data, obj_surface->width,
    517                                obj_surface->height_origin,
    518                                obj_surface->psb_surface);
    519 
    520     /* local video playback */
    521     drv_debug_msg(VIDEO_DEBUG_GENERAL, "MIPI: Use overlay to display.\n");
    522 
    523     /*initialize output destbox using default destbox if it has not been initialized until here.*/
    524     if (output->destw == 0 || output->desth == 0) {
    525         output->destx = (destx > 0) ? destx : 0;
    526         output->desty = (desty > 0) ? desty : 0;
    527         output->destw = ((output->destx + destw) > output->screen_width) ? (output->screen_width - output->destx) : destw;
    528         output->desth = ((output->desty + desth) > output->screen_height) ? (output->screen_height - output->desty) : desth;
    529     }
    530 
    531     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Overlay position = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth);
    532     srcw = srcw <= 2047? srcw : 2047;
    533     vaStatus = psb_putsurface_overlay(ctx, surface,
    534                                       srcx, srcy, srcw, srch,
    535                                       output->destx, output->desty, output->destw, output->desth,
    536                                       flags, OVERLAY_A, PIPEA);
    537 
    538     driver_data->frame_count++;
    539 #endif
    540     return vaStatus;
    541 }
    542