summaryrefslogtreecommitdiff
path: root/src/android/psb_output_android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/psb_output_android.c')
-rw-r--r--src/android/psb_output_android.c579
1 files changed, 452 insertions, 127 deletions
diff --git a/src/android/psb_output_android.c b/src/android/psb_output_android.c
index 1a6466f..2b2072a 100644
--- a/src/android/psb_output_android.c
+++ b/src/android/psb_output_android.c
@@ -8,11 +8,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -38,10 +38,14 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
-#include <cutils/log.h>
#include "psb_android_glue.h"
#include "psb_texstreaming.h"
+#include "psb_output_android.h"
+#include "psb_HDMIExtMode.h"
+#include "pnw_rotate.h"
#include <wsbm/wsbm_manager.h>
+#include <psb_drm.h>
+#include <hardware.h>
#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
#define INIT_OUTPUT_PRIV psb_android_output_p output = (psb_android_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv)
@@ -52,38 +56,55 @@
#define SUBPIC(id) ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id ))
#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
+#define GET_SURFACE_INFO_rotate(psb_surface) ((int) psb_surface->extra_info[5])
+#define GET_SURFACE_INFO_protect(psb_surface) ((int) psb_surface->extra_info[6])
+#define MAX_OVERLAY_IDLE_FRAME 4
-typedef struct _psb_android_output_s {
- /* information of output display */
- unsigned short screen_width;
- unsigned short screen_height;
+enum {
+ eWidiOff = 1,
+ eWidiClone = 2,
+ eWidiExtendedVideo = 3,
+};
+extern unsigned int update_forced;
- /* for memory heap base used by putsurface */
- unsigned char* heap_addr;
-} psb_android_output_s, *psb_android_output_p;
+inline int va2hw_rotation(int va_rotate)
+{
+ switch (va_rotate) {
+ case VA_ROTATION_90:
+ return HAL_TRANSFORM_ROT_270;
+ case VA_ROTATION_180:
+ return HAL_TRANSFORM_ROT_180;
+ case VA_ROTATION_270:
+ return HAL_TRANSFORM_ROT_90;
+defaut:
+ return 0;
+ }
+ return 0;
+}
-void *psb_android_output_init(VADriverContextP ctx)
+unsigned char *psb_android_output_init(VADriverContextP ctx)
{
INIT_DRIVER_DATA;
char put_surface[1024];
struct drm_psb_register_rw_arg regs;
psb_android_output_p output = calloc(1, sizeof(psb_android_output_s));
-
- struct fb_var_screeninfo vinfo = {0};
+ struct fb_var_screeninfo vinfo;
int fbfd = -1;
int ret;
if (output == NULL) {
psb__error_message("Can't malloc memory\n");
- return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ return NULL;
}
+ memset(output, 0, sizeof(psb_android_output_s));
/* Guess the screen size */
output->screen_width = 800;
output->screen_height = 480;
// Open the frame buffer for reading
+ memset(&vinfo, 0, sizeof(vinfo));
fbfd = open("/dev/graphics/fb0", O_RDONLY);
if (fbfd) {
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
@@ -95,36 +116,45 @@ void *psb_android_output_init(VADriverContextP ctx)
/* TS by default */
driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
- driver_data->color_key = 0x0; /*black*/
-
- /* Init CTEXTURE for vaPutSurfaceBuf */
- driver_data->ctexture = 1;
+ driver_data->color_key = 0x000001; /*light blue*/
+ driver_data->overlay_idle_frame = 1;
- if (psb_parse_config("PSB_VIDEO_COVERLAY", &put_surface[0]) == 0) {
- psb__information_message("Putsurface use client overlay\n");
- driver_data->output_method = PSB_PUTSURFACE_FORCE_COVERLAY;
+ if (psb_parse_config("PSB_VIDEO_CTEXTURES", &put_surface[0]) == 0) {
+ psb__information_message("PSB_VIDEO_CTEXTURES is enabled for vaPutSurfaceBuf\n");
+ driver_data->ctexture = 1; /* Init CTEXTURE for vaPutSurfaceBuf */
}
+ if (psb_parse_config("PSB_VIDEO_TS", &put_surface[0]) == 0) {
+ psb__information_message("Putsurface use texstreaming\n");
+ driver_data->output_method = PSB_PUTSURFACE_FORCE_TEXSTREAMING;
+ }
- if (getenv("PSB_VIDEO_COVERLAY")) {
+ if (psb_parse_config("PSB_VIDEO_COVERLAY", &put_surface[0]) == 0) {
psb__information_message("Putsurface use client overlay\n");
driver_data->output_method = PSB_PUTSURFACE_FORCE_COVERLAY;
}
- /*Alway init coverlay for MDFLD*/
- if (IS_MFLD(driver_data))
+
+ if (IS_MFLD(driver_data)) {
driver_data->coverlay = 1;
- /*set PIPEB(HDMI)source format as RGBA*/
- memset(&regs, 0, sizeof(regs));
- regs.subpicture_enable_mask = REGRWBITS_DSPBCNTR;
- drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, &regs, sizeof(regs));
+ output->psb_HDMIExt_info = psb_HDMIExt_init(ctx, output);
+ if (!output->psb_HDMIExt_info) {
+ psb__error_message("Failed to init psb_HDMIExt.\n");
+ free(output);
+ return NULL;
+ }
+ }
- return output;
+ return (unsigned char *)output;
}
VAStatus psb_android_output_deinit(VADriverContextP ctx)
{
+ INIT_DRIVER_DATA;
INIT_OUTPUT_PRIV;
//psb_android_output_p output = GET_OUTPUT_DATA(ctx);
+ if (IS_MFLD(driver_data)) {
+ psb_HDMIExt_deinit(output);
+ }
return VA_STATUS_SUCCESS;
}
@@ -153,34 +183,19 @@ static VAStatus psb_putsurface_ctexture(
obj_surface = SURFACE(surface);
psb_surface = obj_surface->psb_surface;
-// psb_surface->buf.drm_buf;
-// psb_surface->buf.pl_flags;
-
-#if 0
- printf("pl_flags %x\n", psb_surface->buf.pl_flags);
-
- printf("FIXME: not sure how Android app handle rotation?\n"
- "need to revise width & height here?\n");
-
- printf("FIXME: need to prepare a rotation/RAR surface here?\n");
-
- printf("FIXME: camera preview surface is different, all is \n"
- "just one buffer, so a pre_add is needed\n");
- psb__error_message("srcx %d, srcy %d, srcw %d, srch %d, destx %d, desty %d, destw %d,\n"
- "desth %d, width %d height %d, stride %d drm_buf %x\n",
- srcx, srcy, srcw, srch, destx, desty, destw, desth, obj_surface->width,
- obj_surface->height, psb_surface->stride, psb_surface->buf.drm_buf);
-#endif
- psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth,
+ // psb_surface->buf.drm_buf;
+ // psb_surface->buf.pl_flags;
+ psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch,
+ destx, desty, destw, desth, 0, /* no subtitle */
obj_surface->width, obj_surface->height,
psb_surface->stride, psb_surface->buf.drm_buf,
- psb_surface->buf.pl_flags);
+ psb_surface->buf.pl_flags, 1 /* need wrap dst */);
psb_android_postBuffer(offset);
+
return VA_STATUS_SUCCESS;
}
-
VAStatus psb_putsurface_coverlay(
VADriverContextP ctx,
VASurfaceID surface,
@@ -221,6 +236,8 @@ VAStatus psb_putsurface_coverlay(
destw = _destw;
desth = _desth;
+ psb__information_message("psb_putsurface_overlay: src (%d, %d, %d, %d), destx (%d, %d, %d, %d).\n",
+ srcx, srcy, srcw, srch, destx, desty, destw, desth);
/* display by overlay */
vaStatus = psb_putsurface_overlay(
ctx, surface, srcx, srcy, srcw, srch,
@@ -230,11 +247,12 @@ VAStatus psb_putsurface_coverlay(
return vaStatus;
}
-VAStatus psb_PutSurfaceBuf(
+
+VAStatus psb_putsurface_ts(
VADriverContextP ctx,
VASurfaceID surface,
- unsigned char* data,
- int* data_len,
+ unsigned char *android_isurface,
+ int buffer_index,
short srcx,
short srcy,
unsigned short srcw,
@@ -251,20 +269,253 @@ VAStatus psb_PutSurfaceBuf(
INIT_DRIVER_DATA;
INIT_OUTPUT_PRIV;
object_surface_p obj_surface = SURFACE(surface);
- int offset = 0;
- psb_surface_p psb_surface;
- obj_surface = SURFACE(surface);
- psb_surface = obj_surface->psb_surface;
+ if (driver_data->overlay_idle_frame == 0) {
+ psb_android_texture_streaming_resetParams();
+ update_forced = 1;
+ }
- psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth,
- obj_surface->width, obj_surface->height,
- psb_surface->stride, psb_surface->buf.drm_buf,
- psb_surface->buf.pl_flags);
+ /* blend/positioning setting can be called by app directly, or enable VA_ENABLE_BLEND flag to let driver call */
+ if (flags & VA_ENABLE_BLEND)
+ psb_android_texture_streaming_set_blend(destx, desty, destw, desth,
+ driver_data->clear_color,
+ driver_data->blend_color,
+ driver_data->blend_mode);
+ /*cropping can be also used for dynamic resolution change feature, only high to low resolution*/
+ /*by default, srcw and srch is set to video width and height*/
+ if ((0 == srcw) || (0 == srch)) {
+ srcw = obj_surface->width;
+ srch = obj_surface->height_origin;
+ }
+ psb_android_texture_streaming_set_texture_dim(srcw, srch);
+ if (driver_data->va_rotate)
+ psb_android_texture_streaming_set_rotate(va2hw_rotation(driver_data->va_rotate));
+
+#if 0
+ /* use cliprect for crop */
+ if (cliprects && (number_cliprects == 1))
+ psb_android_texture_streaming_set_crop(cliprects->x, cliprects->y, cliprects->width, cliprects->height);
+#endif
+
+ psb_android_texture_streaming_display(buffer_index);
+
+ driver_data->overlay_idle_frame++;
+ update_forced = 0;
+
+ /* current surface is being displayed */
+ if (driver_data->cur_displaying_surface != VA_INVALID_SURFACE)
+ driver_data->last_displaying_surface = driver_data->cur_displaying_surface;
+
+ obj_surface->display_timestamp = GetTickCount();
+ driver_data->cur_displaying_surface = surface;
return VA_STATUS_SUCCESS;
}
+
+static int psb_update_destbox(
+ VADriverContextP ctx
+)
+{
+ INIT_DRIVER_DATA;
+ INIT_OUTPUT_PRIV;
+ short destx;
+ short desty;
+ unsigned short destw;
+ unsigned short desth;
+ VAStatus vaStatus = VA_STATUS_SUCCESS;
+
+ psb_android_get_destbox(&destx, &desty, &destw, &desth);
+ /*psb__information_message("destbox = (%d,%d,%d,%d)\n", destx, desty, destw, desth);*/
+ if ((destx >= 0) && (desty >= 0) &&
+ ((destx + destw) <= output->screen_width) &&
+ ((desty + desth) <= output->screen_height) &&
+ (output->destx != destx ||
+ output->desty != desty ||
+ output->destw != destw ||
+ output->desth != desth)) {
+ output->destx = destx;
+ output->desty = desty;
+ output->destw = destw;
+ output->desth = desth;
+ output->new_destbox = 1;
+
+ LOGD("==========New Destbox=============\n");
+ LOGD("output->destbox = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth);
+ }
+
+ return vaStatus;
+}
+
+static int psb_check_outputmethod(
+ VADriverContextP ctx,
+ VASurfaceID surface,
+ unsigned short srcw,
+ unsigned short srch,
+ void *android_isurface,
+ psb_hdmi_mode *hdmi_mode
+)
+{
+ INIT_DRIVER_DATA;
+ INIT_OUTPUT_PRIV;
+ psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info;
+ object_surface_p obj_surface;
+ int rotation = 0, widi = 0;
+ int delta_rotation = 0;
+ int srf_rotate; /* primary surface rotation */
+ psb_surface_p rotate_surface; /* rotate surface */
+ int rotate_srf_rotate = -1; /* degree of the rotate surface */
+
+ if ((srcw >= 2048) || (srch >= 2048)) {
+ psb__information_message("Clip size extend overlay hw limit, use texstreaming\n");
+ driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
+ return 0;
+ }
+
+ /* use saved status to avoid per-frame checking */
+ if ((driver_data->frame_count % driver_data->outputmethod_checkinterval) != 0) {
+ *hdmi_mode = psb_HDMIExt_get_mode(output);
+ return 0;
+ }
+
+ /* check the status at outputmethod_checkinterval frequency */
+ /* at first check HDMI status */
+ if (psb_HDMIExt_update(ctx, psb_HDMIExt_info)) {
+ psb__error_message("%s: Failed to update HDMIExt info.\n", __FUNCTION__);
+ return -1;
+ }
+
+ *hdmi_mode = psb_HDMIExt_get_mode(output);
+ if ((*hdmi_mode == EXTENDED_VIDEO) || (*hdmi_mode == CLONE)) {
+ unsigned short _destw, _desth;
+ short _pos_x, _pos_y;
+ unsigned short crtc_width = 0, crtc_height = 0;
+ float _slope_xy;
+
+ /* need to handle VA rotation, and set WM rotate to 0
+ * for Android, MIPI0/HDMI has the same WM rotation always
+ */
+ if (driver_data->mipi0_rotation != 0) {
+ driver_data->mipi0_rotation = 0;
+ driver_data->hdmi_rotation = 0;
+ output->new_destbox = 1;
+ psb_RecalcRotate(ctx);
+ }
+
+ psb_HDMIExt_get_prop(output, &crtc_width, &crtc_height);
+
+ /*recalculate the render box to fit the ratio of height/width*/
+ if ((driver_data->extend_rotation == VA_ROTATION_90) ||
+ (driver_data->extend_rotation == VA_ROTATION_270))
+ _slope_xy = (float)srcw / srch;
+ else
+ _slope_xy = (float)srch / srcw;
+
+ _destw = (short)(crtc_height / _slope_xy);
+ _desth = (short)(crtc_width * _slope_xy);
+ if (_destw <= crtc_width) {
+ _desth = crtc_height;
+ _pos_x = (crtc_width - _destw) >> 1;
+ _pos_y = 0;
+ } else {
+ _destw = crtc_width;
+ _pos_x = 0;
+ _pos_y = (crtc_height - _desth) >> 1;
+ }
+ driver_data->render_rect.x = _pos_x;
+ driver_data->render_rect.y = _pos_y;
+ driver_data->render_rect.width = _destw;
+ driver_data->render_rect.height = _desth;
+ psb__information_message("HDMI mode is on (%d), Render Rect: (%d,%d,%d,%d)\n",
+ *hdmi_mode,
+ driver_data->render_rect.x, driver_data->render_rect.y,
+ driver_data->render_rect.width, driver_data->render_rect.height);
+ return 0;
+ }
+
+ /*Update output destbox using layerbuffer's visible region*/
+ psb_update_destbox(ctx);
+
+ if ((driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY)
+ || (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING))
+ return 0;
+
+ /*If overlay can not get correct destbox, use texstreaming.*/
+ if (output->destw == 0 || output->desth == 0 ||
+ ((output->destw == srcw) && (output->desth == srch))) {
+ psb__information_message("No proper destbox, use texstreaming (%dx%d+%d+%d)\n",
+ output->destw, output->desth, output->destx, output->desty);
+ driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
+ return 0;
+ }
+
+ /* HDMI is not enabled */
+ psb_android_surfaceflinger_status(android_isurface, &output->sf_composition, &rotation, &widi);
+ if (widi == eWidiClone) {
+ psb__information_message("WIDI in clone mode, use texstreaming\n");
+ driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
+ driver_data->msvdx_rotate_want = 0;/* disable msvdx rotae */
+
+ return 0;
+ }
+ if (widi == eWidiExtendedVideo) {
+ psb__information_message("WIDI in extend video mode, disable local displaying\n");
+ driver_data->output_method = PSB_PUTSURFACE_NONE;
+ driver_data->msvdx_rotate_want = 0;/* disable msvdx rotae */
+
+ return 0;
+ }
+
+ /* only care local rotation */
+ delta_rotation = Rotation2Angle(driver_data->mipi0_rotation) - Rotation2Angle(rotation);
+ if ((((abs(delta_rotation) == 90) || (abs(delta_rotation) == 270)) && output->new_destbox) ||
+ (abs(delta_rotation) == 180)) {
+ psb__information_message("New rotation degree %d of MIPI0 WM, Recalc rotation\n", rotation);
+ driver_data->mipi0_rotation = rotation;
+ driver_data->hdmi_rotation = rotation;
+
+ psb_RecalcRotate(ctx);
+ }
+ output->new_destbox = 0;
+
+ obj_surface = SURFACE(surface);
+ if (GET_SURFACE_INFO_protect(obj_surface->psb_surface)) {
+ psb__information_message("Protected surface, use overlay\n");
+ driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
+
+ return 0;
+ }
+
+ if (output->sf_composition) {
+ psb__information_message("Composition is detected, use texstreaming\n");
+ driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
+ return 0;
+ }
+
+ srf_rotate = GET_SURFACE_INFO_rotate(obj_surface->psb_surface);
+ rotate_surface = obj_surface->psb_surface_rotate;
+ if (rotate_surface != NULL)
+ rotate_srf_rotate = GET_SURFACE_INFO_rotate(rotate_surface);
+
+ psb__information_message("SF rotation %d, VA rotation %d, final MSVDX rotation %d\n",
+ rotation, driver_data->va_rotate, driver_data->local_rotation);
+ psb__information_message("Primary surface rotation %d, rotated surface rotation %d\n",
+ srf_rotate, rotate_srf_rotate);
+
+ /* The surface rotation is not same with the final rotation */
+ if ((driver_data->local_rotation != 0) &&
+ ((srf_rotate != driver_data->local_rotation) || (rotate_srf_rotate != driver_data->local_rotation))) {
+ psb__information_message("Use texstreaming due to different VA surface rotation and final rotaion\n",
+ srf_rotate, rotate_srf_rotate);
+ driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
+ return 0;
+ }
+
+ driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
+
+ return 0;
+}
+
VAStatus psb_PutSurface(
VADriverContextP ctx,
VASurfaceID surface,
@@ -286,6 +537,10 @@ VAStatus psb_PutSurface(
INIT_OUTPUT_PRIV;
object_surface_p obj_surface;
VAStatus vaStatus = VA_STATUS_SUCCESS;
+ PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv);
+ psb_hdmi_mode hdmi_mode = OFF;
+ int sf_composition = 0, buffer_index, i = 0;
+ int ret = 0;
obj_surface = SURFACE(surface);
if (NULL == obj_surface) {
@@ -294,85 +549,155 @@ VAStatus psb_PutSurface(
return vaStatus;
}
+ if ((NULL == cliprects) && (0 != number_cliprects)) {
+ vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
+ DEBUG_FAILURE;
+ return vaStatus;
+ }
+
+ if ((srcx < 0) || (srcx > obj_surface->width) || (srcw > (obj_surface->width - srcx)) ||
+ (srcy < 0) || (srcy > obj_surface->height_origin) || (srch > (obj_surface->height_origin - srcy))) {
+ psb__error_message("vaPutSurface: source rectangle passed from upper layer is not correct.\n");
+ return VA_STATUS_ERROR_UNKNOWN;
+ }
+ if ((destx < 0) || (desty < 0)) {
+ psb__error_message("vaPutSurface: dest rectangle passed from upper layer is not correct.\n");
+ return VA_STATUS_ERROR_UNKNOWN;
+ }
+
if (driver_data->dummy_putsurface) {
- LOGD("vaPutSurface: dummy mode, return directly\n");
+ psb__information_message("vaPutSurface: dummy mode, return directly\n");
return VA_STATUS_SUCCESS;
}
- if (driver_data->render_device == VA_RENDER_DEVICE_EXTERNAL) {
- /*Use overlay to render external HDMI display*/
+ /* init overlay */
+ if (!driver_data->coverlay_init &&
+ (driver_data->output_method != PSB_PUTSURFACE_FORCE_TEXSTREAMING)) {
+ ret = psb_coverlay_init(ctx);
+ if (ret != 0) {
+ psb__information_message("vaPutSurface: psb_coverlay_init failed. Fallback to texture streaming.\n");
+ driver_data->output_method = PSB_PUTSURFACE_FORCE_TEXSTREAMING;
+ driver_data->coverlay_init = 0;
+ } else
+ driver_data->coverlay_init = 1;
+ }
+
+ /* set the current displaying video frame into kernel */
+ psb_surface_set_displaying(driver_data, obj_surface->width,
+ obj_surface->height_origin,
+ obj_surface->psb_surface);
+
+ /* get the BCD index of current surface */
+ buffer_index = psb_get_video_bcd(ctx, surface);
+ if (buffer_index == -1)
+ psb__error_message("The surface is not registered in BCD, shoud use overlay\n");
+
+ /* exit MRST path at first */
+ if (IS_MRST(driver_data)) {
+ if (driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY) { /* overlay is for testing, not POR */
+ psb__information_message("Force overlay to display\n");
+ vaStatus = psb_putsurface_coverlay(ctx, surface,
+ srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ flags);
+ } else {
+ psb__information_message("Use texstreaming to display.\n");
+ vaStatus = psb_putsurface_ts(ctx, surface, android_isurface, buffer_index,
+ srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, /* number of clip rects in the clip list */
+ flags);
+ }
+
+ return vaStatus;
+ }
+
+ if (psb_android_register_isurface(android_isurface, driver_data->bcd_id, srcw, srch)) {
+ psb__error_message("In psb_PutSurface, android_isurface is not a valid isurface object.\n");
+ return VA_STATUS_ERROR_UNKNOWN;
+ }
+ driver_data->ts_source_created = 1;
+
+ /* time for MFLD platform */
+ psb_check_outputmethod(ctx, surface, srcw, srch, android_isurface, &hdmi_mode);
+ if (driver_data->output_method == PSB_PUTSURFACE_NONE)
+ return VA_STATUS_SUCCESS;
+
+ if (hdmi_mode == UNDEFINED) {
+ psb__information_message("HDMI: Undefined mode, drop the frame.\n");
+ return vaStatus;
+ }
+
+ /* Extvideo: Use overlay to render external HDMI display */
+ if (hdmi_mode == EXTENDED_VIDEO) {
+ psb__information_message("HDMI: ExtVideo mode enabled, use overlay to render external HDMI display.\n");
+ /*we also need to clear local display if colorkey dirty.*/
+ if (driver_data->overlay_idle_frame != 0) {
+ psb_android_texture_streaming_set_background_color(driver_data->color_key | 0xff000000);
+ psb_android_texture_streaming_display(buffer_index);
+ driver_data->overlay_idle_frame = 0;
+ }
vaStatus = psb_putsurface_overlay(ctx, surface,
srcx, srcy, srcw, srch,
driver_data->render_rect.x, driver_data->render_rect.y,
driver_data->render_rect.width, driver_data->render_rect.height,
flags, OVERLAY_A, PIPEB);
- } else if ((driver_data->render_mode & VA_RENDER_MODE_LOCAL_OVERLAY) ||
- (driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY) ||
- (driver_data->output_method == PSB_PUTSURFACE_COVERLAY)) {
- LOGD("In psb_PutSurface, use overlay to display video.\n");
- LOGD("srcx is %d, srcy is %d, srcw is %d, srch is %d, destx is %d, desty is %d, destw is %d, desth is %d.\n", \
- srcx, srcy, srcw, srch, destx, desty, destw, desth);
- /*Use overlay to render local display*/
- if (destw > output->screen_width)
- destw = output->screen_width;
- if (desth > output->screen_height)
- desth = output->screen_height;
- vaStatus = psb_putsurface_overlay(ctx, surface,
- srcx, srcy, srcw, srch,
- destx, desty, destw, desth,
- flags, OVERLAY_A, PIPEA);
- /*Use overlay to render external HDMI display*/
- if (driver_data->render_device & VA_RENDER_DEVICE_EXTERNAL) {
- vaStatus = psb_putsurface_overlay(ctx, surface,
- srcx, srcy, srcw, srch,
- driver_data->render_rect.x, driver_data->render_rect.y,
- driver_data->render_rect.width, driver_data->render_rect.height,
- flags, OVERLAY_C, PIPEB);
- }
+
+ return vaStatus;
+ }
+
+ /* Clone mode: Use TS to render both MIPI and HDMI display */
+ if (hdmi_mode == CLONE) {
+ psb__information_message("HDMI: Clone mode enabled, use texsteaming for both devices\n");
+ vaStatus = psb_putsurface_ts(ctx, surface, android_isurface, buffer_index,
+ srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, /* number of clip rects in the clip list */
+ flags);
+ return vaStatus;
+ }
+
+ /* local video playback */
+ if ((driver_data->output_method == PSB_PUTSURFACE_TEXSTREAMING) ||
+ (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING)) {
+ psb__information_message("MIPI: Use texstreaming to display.\n");
+
+ vaStatus = psb_putsurface_ts(ctx, surface, android_isurface, buffer_index,
+ srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, /* number of clip rects in the clip list */
+ flags);
} else {
- LOGD("In psb_PutSurface, use texture streaming to display video.\n");
- LOGD("In psb_PutSurface, call psb_android_register_isurface to create texture streaming source, srcw is %d, srch is %d.\n", srcw, srch);
- if (psb_android_register_isurface(android_isurface, driver_data->bcd_id, srcw, srch)) {
- LOGE("In psb_PutSurface, android_isurface is not a valid isurface object.\n");
- return VA_STATUS_ERROR_UNKNOWN;
- }
- /*blend/positioning setting can be called by app directly, or enable VA_ENABLE_BLEND flag to let driver call*/
- if (flags & VA_ENABLE_BLEND)
- psb_android_texture_streaming_set_blend(destx, desty, destw, desth,
- driver_data->clear_color,
- driver_data->blend_color,
- driver_data->blend_mode);
- /*cropping can be also used for dynamic resolution change feature, only high to low resolution*/
- /*by default, srcw and srch is set to video width and height*/
- if ((0 == srcw) || (0 == srch)) {
- srcw = obj_surface->width;
- srch = obj_surface->height_origin;
- }
- psb_android_texture_streaming_set_crop(srcx, srcy, srcw, srch);
-
- BC_Video_ioctl_package ioctl_package;
- psb_surface_p psb_surface;
- psb_surface = obj_surface->psb_surface;
- ioctl_package.ioctl_cmd = BC_Video_ioctl_get_buffer_index;
- ioctl_package.device_id = driver_data->bcd_id;
- ioctl_package.inputparam = (int)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
-
- if (drmCommandWriteRead(driver_data->drm_fd, driver_data->bcd_ioctrl_num, &ioctl_package, sizeof(ioctl_package)) != 0) {
- psb__error_message("Failed to get buffer index from buffer class video driver (errno=%d).\n", errno);
- return VA_STATUS_ERROR_UNKNOWN;
+ psb__information_message("MIPI: Use overlay to display.\n");
+
+ /*initialize output destbox using default destbox if it has not been initialized until here.*/
+ if (output->destw == 0 || output->desth == 0) {
+ output->destx = (destx > 0) ? destx : 0;
+ output->desty = (desty > 0) ? desty : 0;
+ output->destw = ((output->destx + destw) > output->screen_width) ? (output->screen_width - output->destx) : destw;
+ output->desth = ((output->desty + desth) > output->screen_height) ? (output->screen_height - output->desty) : desth;
}
- LOGD("buffer handle is %d and buffer index is %d.\n", ioctl_package.inputparam, ioctl_package.outputparam);
- psb_android_texture_streaming_display(ioctl_package.outputparam);
-
- /*Use overlay to render external HDMI display*/
- if (driver_data->render_device & VA_RENDER_DEVICE_EXTERNAL) {
- vaStatus = psb_putsurface_overlay(ctx, surface,
- srcx, srcy, srcw, srch,
- driver_data->render_rect.x, driver_data->render_rect.y,
- driver_data->render_rect.width, driver_data->render_rect.height,
- flags, OVERLAY_A, PIPEB);
+
+ /* Hack for repaint color key to black(0,0,0). */
+ if (driver_data->overlay_idle_frame != 0) {
+ psb__information_message("Paint color key to 0x%x\n", driver_data->color_key);
+ psb_android_texture_streaming_set_background_color(driver_data->color_key | 0xff000000);
+ psb_android_texture_streaming_display(buffer_index);
+ driver_data->overlay_idle_frame = 0;
}
+
+ psb__information_message("Overlay position = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth);
+ vaStatus = psb_putsurface_overlay(ctx, surface,
+ srcx, srcy, srcw, srch,
+ output->destx, output->desty, output->destw, output->desth,
+ flags, OVERLAY_A, PIPEA);
}
+ if (driver_data->overlay_idle_frame == MAX_OVERLAY_IDLE_FRAME)
+ psb_coverlay_stop(ctx);
+
+ driver_data->frame_count++;
+
+
return vaStatus;
}