blob: eca8ba86309d1843f4b12eafd72585df47d73a11 [file] [log] [blame]
/*
* drivers/amlogic/media/video_processor/ppmgr/ppmgr_3d.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/amlogic/media/vout/vinfo.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/platform_device.h>
#include <linux/amlogic/media/frame_sync/timestamp.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
/*#include <linux/amlogic/amports/vfp.h>*/
#include "vfp.h"
/*#include <mach/am_regs.h>*/
#include <linux/amlogic/media/utils/amlog.h>
#include <linux/reset.h>
#include <linux/amlogic/media/ge2d/ge2d.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/semaphore.h>
#include <linux/sched.h>
#include "ppmgr_log.h"
#include "ppmgr_pri.h"
#include "ppmgr_dev.h"
#include <linux/amlogic/media/ppmgr/ppmgr.h>
#include <linux/amlogic/media/ppmgr/ppmgr_status.h>
#include <linux/io.h>
#include "ppmgr_3d.h"
#define VF_POOL_SIZE 4
#define PPMGR3D_INFO(fmt, args...) pr_info("PPMGR3D: info: "fmt"", ## args)
#define PPMGR3D_DBG(fmt, args...) pr_debug("PPMGR3D: dbg: "fmt"", ## args)
#define PPMGR3D_WARN(fmt, args...) pr_warn("PPMGR3D: warn: "fmt"", ## args)
#define PPMGR3D_ERR(fmt, args...) pr_err("PPMGR3D: err: "fmt"", ## args)
static int cur_process_type;
static int mask_canvas_index = -1;
static int ppmgr_3d_clear_count;
struct Process3d_t {
unsigned int all_mode;
unsigned char mode;
unsigned char src_format;
unsigned char switch_flag;
unsigned char _3d_to_2d_use_frame;
unsigned char _2d_to_3d_type;
unsigned char double_type;
unsigned int _2d_3d_control;
unsigned int _2d_3d_control_value;
/*unsigned direction; //0: 0 degree, 1: 90, 2: 180, 3:270*/
};
struct display_frame_s {
int frame_top;
int frame_left;
int frame_width;
int frame_height;
int content_top;
int content_left;
int content_width;
int content_height;
};
/*extern void ppmgr_vf_put_dec(struct vframe_s *vf);
*extern u32 index2canvas(u32 index);
*extern struct vfq_s q_ready;
*extern struct vfq_s q_free;
*extern int get_bypass_mode(void);
*/
static struct Process3d_t _3d_process = {0};
void Reset3Dclear(void)
{
ppmgr_3d_clear_count = VF_POOL_SIZE;
}
void Set3DProcessPara(unsigned int mode)
{
if (_3d_process.all_mode != mode) {
memset(&_3d_process, 0, sizeof(struct Process3d_t));
_3d_process.all_mode = mode;
_3d_process.mode = mode & PPMGR_3D_PROCESS_MODE_MASK;
_3d_process.src_format =
(mode & PPMGR_3D_PROCESS_SRC_FOMRAT_MASK)
>> PPMGR_3D_PROCESS_SRC_FORMAT_SHIFT;
_3d_process.switch_flag =
(mode & PPMGR_3D_PROCESS_SWITCH_FLAG) ? 1 : 0;
_3d_process._3d_to_2d_use_frame =
(mode & PPMGR_3D_PROCESS_3D_TO_2D_SRC_FRAME) ? 1 : 0;
_3d_process._2d_to_3d_type =
(mode & PPMGR_3D_PROCESS_2D_TO_3D_MASK)
>> PPMGR_3D_PROCESS_2D_TO_3D_SHIFT;
_3d_process.double_type = (mode & PPMGR_3D_PROCESS_DOUBLE_TYPE)
>> PPMGR_3D_PROCESS_DOUBLE_TYPE_SHIFT;
_3d_process._2d_3d_control =
(mode &
PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_MASK) >>
PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_SHIFT;
if (_3d_process._2d_3d_control > 0) {
_3d_process._2d_3d_control_value =
(mode &
PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_VALUE_MASK) >>
PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_VALUE_SHIFT;
if ((_3d_process.mode ==
PPMGR_3D_PROCESS_MODE_2D_TO_3D)
&& (!_3d_process._2d_3d_control_value))
_3d_process._2d_3d_control_value = 0x10;
} else {
_3d_process._2d_3d_control_value = 0;
}
/* _3d_process.direction = (mode & PPMGR_3D_PROCESS_3D_ROTATE_DIRECTION_MASK)
* >>PPMGR_3D_PROCESS_3D_ROTATE_DIRECTION_VALUE_SHIFT;
*/
/* printk("-- ppmgr 3d process 0x%x: mode:%d, src format:%d, switch flag:%d, 3d
* to 2d frame: %d, 2d to 3d:%d, double type:%d, control mode: %d, control
* value: %d, rotate direction: %d,
*/
/* _3d_process.all_mode, _3d_process.mode, _3d_process.src_format,
* _3d_process.switch_flag,
*/
/* _3d_process._3d_to_2d_use_frame, _3d_process._2d_to_3d_type,
* _3d_process.double_type,
*/
/* _3d_process._2d_3d_control, _3d_process._2d_3d_control_value,
* _3d_process.direction);
*/
}
}
int get_mid_process_type(struct vframe_s *vf)
{
int process_type = 0;
if (!vf) {
process_type = TYPE_NONE;
return process_type;
}
if (_3d_process.mode == PPMGR_3D_PROCESS_MODE_3D_ENABLE) {
if (_3d_process.src_format == PPMGR_3D_PROCESS_SRC_FOMRAT_LR) {
process_type = TYPE_3D_LR;
} else if (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB) {
process_type = TYPE_3D_TB;
} else { /* auto mode or others*/
switch (vf->trans_fmt) {
case TVIN_TFMT_3D_TB:
process_type = TYPE_3D_TB;
break;
case TVIN_TFMT_3D_FP:
process_type = TYPE_3D_LR;
break;
case TVIN_TFMT_3D_LRH_OLOR:
case TVIN_TFMT_3D_LRH_OLER:
case TVIN_TFMT_3D_LRH_ELOR:
case TVIN_TFMT_3D_LRH_ELER:
process_type = TYPE_3D_LR;
break;
default:
process_type = TYPE_NONE;
break;
}
}
} else if (_3d_process.mode == PPMGR_3D_PROCESS_MODE_3D_TO_2D) {
if (_3d_process.src_format == PPMGR_3D_PROCESS_SRC_FOMRAT_LR) {
process_type = TYPE_3D_TO_2D_LR;
} else if (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB) {
process_type = TYPE_3D_TO_2D_TB;
} else { /* auto mode or others*/
switch (vf->trans_fmt) {
case TVIN_TFMT_3D_TB:
process_type = TYPE_3D_TO_2D_TB;
break;
case TVIN_TFMT_3D_FP:
process_type = TYPE_3D_TO_2D_LR;
break;
case TVIN_TFMT_3D_LRH_OLOR:
case TVIN_TFMT_3D_LRH_OLER:
case TVIN_TFMT_3D_LRH_ELOR:
case TVIN_TFMT_3D_LRH_ELER:
process_type = TYPE_3D_TO_2D_LR;
break;
default:
process_type = TYPE_NONE;
break;
}
}
} else if (_3d_process.mode == PPMGR_3D_PROCESS_MODE_2D_TO_3D) {
process_type = TYPE_2D_TO_3D;
} else {
process_type = TYPE_NONE;
}
return process_type;
}
int is_mid_local_source(struct vframe_s *vf)
{
int ret = 0;
if (vf->type & VIDTYPE_VIU_422)
ret = 0;
else
ret = 1;
return ret;
}
int is_mid_mvc_need_process(struct vframe_s *vf)
{
int ret = 0;
int process_type = get_mid_process_type(vf);
switch (process_type) {
/*case TYPE_3D_LR:*/
case TYPE_3D_TO_2D_LR:
ret = 1;
break;
default:
break;
}
return ret;
}
static int is_vertical_sample_enable(struct vframe_s *vf)
{
int ret = 0;
if ((vf->type & VIDTYPE_INTERLACE_BOTTOM) || (vf->type
& VIDTYPE_INTERLACE_TOP)) {
ret = 1;
}
return ret;
}
static int get_input_format(struct vframe_s *vf)
{
int format = GE2D_FORMAT_M24_YUV420;
if (vf->type & VIDTYPE_VIU_NV21)
format = GE2D_FORMAT_M24_NV21;
else
format = GE2D_FORMAT_M24_YUV420;
if (vf->type & VIDTYPE_VIU_422) {
format = GE2D_FORMAT_S16_YUV422;
} else {
if (is_vertical_sample_enable(vf)) {
if (vf->type & VIDTYPE_INTERLACE_BOTTOM) {
format = format
| (GE2D_FMT_M24_YUV420B & (3 << 3));
} else if (vf->type & VIDTYPE_INTERLACE_TOP) {
format = format
| (GE2D_FORMAT_M24_YUV420T & (3 << 3));
}
} else {
if (vf->type & VIDTYPE_VIU_NV21)
format = GE2D_FORMAT_M24_NV21;
else
format = GE2D_FORMAT_M24_YUV420;
}
}
return format;
}
static int get_input_frame(struct vframe_s *vf, struct display_frame_s *frame)
{
if (frame == NULL)
return -1;
if (vf->type & VIDTYPE_MVC) {
frame->content_top = vf->left_eye.start_y;
frame->content_left = vf->left_eye.start_x;
frame->content_width = vf->left_eye.width;
frame->content_height = vf->left_eye.height;
frame->frame_top = vf->left_eye.start_y;
frame->frame_left = vf->left_eye.start_x;
frame->frame_width = vf->left_eye.width;
frame->frame_height = vf->left_eye.height;
return 0;
}
/*tv in case , need detect the black bar*/
if ((vf->prop.bbar.bottom) && (vf->prop.bbar.right)
&& (vf->prop.bbar.right > vf->prop.bbar.left)
&& (vf->prop.bbar.bottom > vf->prop.bbar.top)) {
switch (vf->trans_fmt) {
case TVIN_TFMT_2D:
frame->content_top = vf->prop.bbar.top;
frame->content_left = vf->prop.bbar.left;
frame->content_width = vf->prop.bbar.right
- vf->prop.bbar.left;
frame->content_height = vf->prop.bbar.bottom
- vf->prop.bbar.top;
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
case TVIN_TFMT_3D_FP:
frame->content_top = vf->left_eye.start_y;
frame->content_left = vf->left_eye.start_x;
frame->content_width = vf->left_eye.width;
frame->content_height = vf->left_eye.height;
frame->frame_top = vf->left_eye.start_y;
frame->frame_left = vf->left_eye.start_x;
frame->frame_width = vf->left_eye.width;
frame->frame_height = vf->left_eye.height;
break;
default:
frame->content_top = vf->prop.bbar.top;
frame->content_left = vf->prop.bbar.left;
frame->content_width = vf->prop.bbar.right
- vf->prop.bbar.left;
frame->content_height = vf->prop.bbar.bottom
- vf->prop.bbar.top;
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
}
/* printk("full_frame: format is %d,
* top is %d , left is %d , width is %d,
* height is %d\n", vf->trans_fmt,
* frame->content_top , frame->content_left,
* frame->content_width, frame->content_height);
*/
} else {
switch (vf->trans_fmt) {
case TVIN_TFMT_2D:
frame->content_top = 0;
frame->content_left = 0;
frame->content_width = vf->width;
frame->content_height = vf->height;
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
case TVIN_TFMT_3D_FP:
frame->content_top = vf->left_eye.start_y;
frame->content_left = vf->left_eye.start_x;
frame->content_width = vf->left_eye.width;
frame->content_height = vf->left_eye.height;
frame->frame_top = vf->left_eye.start_y;
frame->frame_left = vf->left_eye.start_x;
frame->frame_width = vf->left_eye.width;
frame->frame_height = vf->left_eye.height;
break;
default:
frame->content_top = 0;
frame->content_left = 0;
frame->content_width = vf->width;
frame->content_height = vf->height;
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
}
}
return 0;
}
static int get_input_l_frame(struct vframe_s *vf, struct display_frame_s *frame)
{
int content_top, content_left, content_width, content_height;
if (frame == NULL)
return -1;
if (vf->type & VIDTYPE_MVC) {
frame->content_top = vf->left_eye.start_y;
frame->content_left = vf->left_eye.start_x;
frame->content_width = vf->left_eye.width;
frame->content_height = vf->left_eye.height;
frame->frame_top = vf->left_eye.start_y;
frame->frame_left = vf->left_eye.start_x;
frame->frame_width = vf->left_eye.width;
frame->frame_height = vf->left_eye.height;
return 0;
}
/*tv in case , need detect the black bar*/
if ((vf->prop.bbar.bottom) && (vf->prop.bbar.right)
&& (vf->prop.bbar.right > vf->prop.bbar.left)
&& (vf->prop.bbar.bottom > vf->prop.bbar.top)) {
switch (vf->trans_fmt) {
case TVIN_TFMT_2D:
content_top = vf->prop.bbar.top;
content_left = vf->prop.bbar.left;
content_width = vf->prop.bbar.right
- vf->prop.bbar.left;
content_height = vf->prop.bbar.bottom
- vf->prop.bbar.top;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
case TVIN_TFMT_3D_FP:
frame->content_top = vf->left_eye.start_y;
frame->content_left = vf->left_eye.start_x;
frame->content_width = vf->left_eye.width;
frame->content_height = vf->left_eye.height;
frame->frame_top = vf->left_eye.start_y;
frame->frame_left = vf->left_eye.start_x;
frame->frame_width = vf->left_eye.width;
frame->frame_height = vf->left_eye.height;
break;
default:
content_top = vf->prop.bbar.top;
content_left = vf->prop.bbar.left;
content_width = vf->prop.bbar.right
- vf->prop.bbar.left;
content_height = vf->prop.bbar.bottom
- vf->prop.bbar.top;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
}
/* printk("lframe: format is %d,
* top is %d , left is %d , width is %d,
* height is %d\n", vf->trans_fmt , frame->content_top,
* frame->content_left, frame->content_width,
* frame->content_height);
*/
} else {
switch (vf->trans_fmt) {
case TVIN_TFMT_2D:
content_top = 0;
content_left = 0;
content_width = vf->width;
content_height = vf->height;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
case TVIN_TFMT_3D_FP:
frame->content_top = vf->left_eye.start_y;
frame->content_left = vf->left_eye.start_x;
frame->content_width = vf->left_eye.width;
frame->content_height = vf->left_eye.height;
frame->frame_top = vf->left_eye.start_y;
frame->frame_left = vf->left_eye.start_x;
frame->frame_width = vf->left_eye.width;
frame->frame_height = vf->left_eye.height;
break;
default:
content_top = 0;
content_left = 0;
content_width = vf->width;
content_height = vf->height;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
}
}
return 0;
}
static int get_input_r_frame(struct vframe_s *vf, struct display_frame_s *frame)
{
int content_top, content_left, content_width, content_height;
if (frame == NULL)
return -1;
if (vf->type & VIDTYPE_MVC) {
frame->content_top = vf->right_eye.start_y;
frame->content_left = vf->right_eye.start_x;
frame->content_width = vf->right_eye.width;
frame->content_height = vf->right_eye.height;
frame->frame_top = vf->right_eye.start_y;
frame->frame_left = vf->right_eye.start_x;
frame->frame_width = vf->right_eye.width;
frame->frame_height = vf->right_eye.height;
return 0;
}
/*tv in case , need detect the black bar*/
if ((vf->prop.bbar.bottom) && (vf->prop.bbar.right)
&& (vf->prop.bbar.right > vf->prop.bbar.left)
&& (vf->prop.bbar.bottom > vf->prop.bbar.top)) {
switch (vf->trans_fmt) {
case TVIN_TFMT_2D:
content_top = vf->prop.bbar.top;
content_left = vf->prop.bbar.left;
content_width = vf->prop.bbar.right
- vf->prop.bbar.left;
content_height = vf->prop.bbar.bottom
- vf->prop.bbar.top;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top
+ content_height / 2;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_width / 2
+ content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
case TVIN_TFMT_3D_FP:
frame->content_top = vf->right_eye.start_y;
frame->content_left = vf->right_eye.start_x;
frame->content_width = vf->right_eye.width;
frame->content_height = vf->right_eye.height;
frame->frame_top = vf->right_eye.start_y;
frame->frame_left = vf->right_eye.start_x;
frame->frame_width = vf->right_eye.width;
frame->frame_height = vf->right_eye.height;
break;
default:
content_top = vf->prop.bbar.top;
content_left = vf->prop.bbar.left;
content_width = vf->prop.bbar.right
- vf->prop.bbar.left;
content_height = vf->prop.bbar.bottom
- vf->prop.bbar.top;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top
+ content_height / 2;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_width / 2
+ content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
}
/* printk("rframe : format is %d,
* top is %d , left is %d , width is %d,
* height is %d\n", vf->trans_fmt,
* frame->content_top , frame->content_left,
* frame->content_width, frame->content_height);
*/
} else {
switch (vf->trans_fmt) {
case TVIN_TFMT_2D:
content_top = 0;
content_left = 0;
content_width = vf->width;
content_height = vf->height;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format
== PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top
+ content_height / 2;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_width / 2
+ content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
case TVIN_TFMT_3D_FP:
frame->content_top = vf->right_eye.start_y;
frame->content_left = vf->right_eye.start_x;
frame->content_width = vf->right_eye.width;
frame->content_height = vf->right_eye.height;
frame->frame_top = vf->right_eye.start_y;
frame->frame_left = vf->right_eye.start_x;
frame->frame_width = vf->right_eye.width;
frame->frame_height = vf->right_eye.height;
break;
default:
content_top = 0;
content_left = 0;
content_width = vf->width;
content_height = vf->height;
if ((cur_process_type == TYPE_3D_TB)
|| (cur_process_type
== TYPE_3D_TO_2D_TB)
|| (_3d_process.src_format ==
PPMGR_3D_PROCESS_SRC_FOMRAT_TB)) {
frame->content_top = content_top
+ content_height / 2;
frame->content_left = content_left;
frame->content_width = content_width;
frame->content_height = content_height / 2;
} else {
frame->content_top = content_top;
frame->content_left = content_width / 2
+ content_left;
frame->content_width = content_width / 2;
frame->content_height = content_height;
}
frame->frame_top = 0;
frame->frame_left = 0;
frame->frame_width = vf->width;
frame->frame_height = vf->height;
break;
}
}
return 0;
}
static int get_output_rect_after_ratio(struct vframe_s *vf, int *top, int *left,
int *width, int *height, int in_width,
int in_height, int output_width,
int output_height, unsigned int angle)
{
int t = 0, l = 0, w = 0, h = 0;
int current_view_mode = 0;
int ar = 0x100;
unsigned char doublemode = _3d_process.double_type;
w = output_width;
h = output_height;
if (doublemode == PPMGR_3D_PROCESS_DOUBLE_TYPE_HOR)
in_width = in_width << 1;
else if (doublemode == PPMGR_3D_PROCESS_DOUBLE_TYPE_VER)
in_height = in_height << 1;
if (vf->ratio_control) {
ar = (vf->ratio_control >> DISP_RATIO_ASPECT_RATIO_BIT) & 0x3ff;
if (doublemode == PPMGR_3D_PROCESS_DOUBLE_TYPE_HOR)
ar = ar >> 1;
else if (doublemode == PPMGR_3D_PROCESS_DOUBLE_TYPE_VER)
ar = ar << 1;
} else {
ar = (in_height << 8) / in_width;
}
current_view_mode = get_ppmgr_viewmode();
if (current_view_mode == VIEWMODE_NORMAL) {
if (output_width > output_height) { /*panel 1280*768 case*/
if (angle & 1) {
if ((in_width * 16) == (in_height * 9))
current_view_mode = VIEWMODE_FULL;
} else {
if ((in_width * 9) == (in_height * 16))
current_view_mode = VIEWMODE_FULL;
}
} else { /*panel 800*1280 case*/
if (angle & 1) {
if ((in_width * 9) == (in_height * 16))
current_view_mode = VIEWMODE_FULL;
} else {
if ((in_width * 16) == (in_height * 9))
current_view_mode = VIEWMODE_FULL;
}
}
}
switch (current_view_mode) {
case VIEWMODE_4_3:
ar = 0xc0;
break;
case VIEWMODE_16_9:
ar = 0x90;
break;
case VIEWMODE_FULL:
*top = 0;
*left = 0;
*width = output_width;
*height = output_height;
return 0;
case VIEWMODE_1_1:
if (angle & 1) {
int swap = in_width;
in_width = in_height;
in_height = swap;
}
break;
case VIEWMODE_NORMAL:
default:
break;
}
if (angle & 1)
ar = 0x10000 / ar;
if ((ar * output_width) > (output_height << 8)) {
if ((current_view_mode == VIEWMODE_1_1) && (in_height
<= output_height)) {
l = (output_width - in_width) >> 1;
t = (output_height - in_height) >> 1;
} else {
w = (output_height << 8) / ar;
l = (output_width - w) / 2;
}
} else {
if ((current_view_mode == VIEWMODE_1_1) && (in_width
<= output_width)) {
l = (output_width - in_width) >> 1;
t = (output_height - in_height) >> 1;
} else {
h = (output_width * ar) >> 8;
t = (output_height - h) / 2;
}
}
l &= ~1;
t &= ~1;
w = output_width - 2 * l;
h = output_height - 2 * t;
*top = t;
*left = l;
*width = w;
*height = h;
return 0;
}
/*******************************************************************/
/* for decoder input processing
* 1. output window should 1:1 as source frame size
* 2. keep the frame ratio
* 3. input format should be YUV420 , output format should be YUV444
*/
static void process_none(struct vframe_s *vf, struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config)
{
}
/*static int ratio_value = 10; // 0~255*/
/* for 90 degree and 270 degree, use interlace mode to output mix data.*/
void process_2d_to_3d_ex(struct vframe_s *vf, struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config,
unsigned int angle)
{
struct vframe_s *new_vf;
struct ppframe_s *pp_vf;
struct display_frame_s input_frame;
struct canvas_s cs0, cs1, cs2, cd;
int t, l, w, h;
int canvas_width = ppmgr_device.canvas_width;
int canvas_height = ppmgr_device.canvas_height;
unsigned char switch_flag = _3d_process.switch_flag;
int x_offset = 0, dir = 0;
unsigned int scale_down = get_ppmgr_scaledown() + 1;
int pic_struct = 0;
new_vf = vfq_pop(&q_free);
if (_3d_process._2d_3d_control ==
PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_LEFT_MOVE) {
x_offset = _3d_process._2d_3d_control_value;
} else if (_3d_process._2d_3d_control
== PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_RIGHT_MOVE) {
x_offset = _3d_process._2d_3d_control_value;
dir = 1;
} else {
x_offset = 0;
}
if (unlikely((!new_vf) || (!vf)))
return;
/*int interlace_mode = vf->type & VIDTYPE_TYPEMASK;*/
pp_vf = to_ppframe(new_vf);
pp_vf->dec_frame = NULL;
new_vf->ratio_control = ((scale_down > 1) ?
DISP_RATIO_FORCE_FULL_STRETCH :
DISP_RATIO_FORCE_NORMALWIDE)
| DISP_RATIO_FORCECONFIG;
new_vf->duration = vf->duration;
new_vf->duration_pulldown = vf->duration_pulldown;
new_vf->pts = vf->pts;
if (ppmgr_device.disp_width > ppmgr_device.disp_height)
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD;
else
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD | VIDTYPE_VSCALE_DISABLE;
new_vf->canvas0Addr = new_vf->canvas1Addr = index2canvas(pp_vf->index);
get_input_frame(vf, &input_frame);
new_vf->width = ppmgr_device.disp_width;
new_vf->height = ppmgr_device.disp_height;
if (ppmgr_3d_clear_count > 0) {
/*clear rect*/
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->src_planes[0].addr = cd.addr;
ge2d_config->src_planes[0].w = cd.width;
ge2d_config->src_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = canvas_width;
ge2d_config->src_para.height = canvas_height;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
ppmgr_vf_put_dec(vf);
vfq_push(&q_free, new_vf);
return;
}
fillrect(context, 0, 0, canvas_width, canvas_height,
0x008080ff);
ppmgr_3d_clear_count--;
}
if (vf->type & VIDTYPE_MVC)
pic_struct = (GE2D_FORMAT_M24_YUV420T & (3 << 3));
else
pic_struct = 0;
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444
| (switch_flag ?
(GE2D_FORMAT_M24_YUV420B & (3 << 3)) :
(GE2D_FORMAT_M24_YUV420T & (3 << 3)));
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height >> 1;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
/* printk("--first frame ex: %d, %d, %d, %d.out put:
* %d, %d, %d, %d. frame size: %d, %d.\n",
*/
/* input_frame.content_left, input_frame.content_top,
* input_frame.content_width, input_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
}
}
if (is_vertical_sample_enable(vf)) {
stretchblt_noalpha(context, input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
input_frame.content_height / 2, l,
t / 2, w, h / 2);
} else {
stretchblt_noalpha(
context,
input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
(pic_struct) ?
(input_frame.content_height / 2) :
input_frame.content_height,
l, t / 2, w, h / 2);
}
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444
| (switch_flag ?
(GE2D_FORMAT_M24_YUV420T & (3 << 3)) :
(GE2D_FORMAT_M24_YUV420B & (3 << 3)));
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height >> 1;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR(
"++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (x_offset) {
if (angle & 1) {
int dst_h = 0;
if (dir) { /*move down*/
if ((t + x_offset + h) <= new_vf->height) {
if (angle == 3) {
t = t - x_offset;
t &= ~1;
} else {
t = t + x_offset;
t &= ~1;
}
} else if ((t + x_offset) < new_vf->height) {
t = t + x_offset;
t &= ~1;
dst_h = new_vf->height - t;
input_frame.content_width =
((((input_frame.content_width
* dst_h) << 8) + 0x80) / h)
>> 8;
h = dst_h;
if (angle == 3)
t = 0;
} else {
PPMGR3D_ERR(
"++2d->3d error,out of range1.\n");
}
} else {/*move up*/
if (t >= x_offset) { /*only pan*/
if (angle == 3) {
t = t + x_offset;
t &= ~1;
} else {
t = t - x_offset;
t &= ~1;
}
} else if ((t + h) > x_offset) { /*need cut*/
int src_w = 0, src_l = 0;
t = 0;
dst_h = h + t - x_offset;
src_w = ((((input_frame.content_width
* dst_h)
<< 8)
+ 0x80)
/ h)
>> 8;
h = dst_h;
src_l =
input_frame.content_left
+ input_frame.content_width
- src_w;
src_l &= ~1;
input_frame.content_width =
input_frame.content_width
+ input_frame.content_left
- src_l;
input_frame.content_left = src_l;
if (angle == 3)
t = t + x_offset;
} else {
PPMGR3D_ERR(
"++2d->3d error, out of range2.\n");
}
}
} else {
int dst_w = 0;
if (dir) { /*move right*/
if ((l + x_offset + w) <= new_vf->width) {
if ((angle == 1) || (angle == 2)) {
l = l - x_offset;
l &= ~1;
} else {
l = l + x_offset;
l &= ~1;
}
} else if ((l + x_offset) < new_vf->width) {
l = l + x_offset;
l &= ~1;
dst_w = new_vf->width - l;
input_frame.content_width =
((((input_frame.content_width
* dst_w) << 8) + 0x80) / w)
>> 8;
w = dst_w;
if ((angle == 1) || (angle == 2))
l = 0;
} else {
PPMGR3D_ERR(
"++2d->3d error, out of range1.\n");
}
} else {/*move left*/
if (l >= x_offset) { /*only pan*/
if ((angle == 1) || (angle == 2)) {
l = l + x_offset;
l &= ~1;
} else {
l = l - x_offset;
l &= ~1;
}
} else if ((l + w) > x_offset) { /*need cut*/
int src_w = 0, src_l = 0;
l = 0;
dst_w = w + l - x_offset;
src_w = ((((input_frame.content_width
* dst_w)
<< 8)
+ 0x80)
/ w)
>> 8;
w = dst_w;
src_l =
input_frame.content_left
+ input_frame.content_width
- src_w;
src_l &= ~1;
input_frame.content_width =
input_frame.content_width
+ input_frame.content_left
- src_l;
input_frame.content_left = src_l;
if ((angle == 1) || (angle == 2))
l = l + x_offset;
} else {
PPMGR3D_ERR(
"++2d->3d error, out of range2.\n");
}
}
}
}
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
new_vf->width = new_vf->width / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
new_vf->height = new_vf->height / scale_down;
}
}
if (is_vertical_sample_enable(vf)) {
stretchblt_noalpha(context, input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
input_frame.content_height / 2, l,
t / 2, w, h / 2);
} else {
stretchblt_noalpha(
context,
input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
(pic_struct) ?
(input_frame.content_height / 2) :
input_frame.content_height,
l, t / 2, w, h / 2);
}
/* printk("--second frame ex: %d, %d, %d, %d.
* out put:%d, %d, %d, %d. frame size: %d, %d.\n",
*/
/* input_frame.content_left, input_frame.content_top,
* input_frame.content_width, input_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
ppmgr_vf_put_dec(vf);
vfq_push(&q_ready, new_vf);
}
static void process_2d_to_3d(struct vframe_s *vf,
struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config,
unsigned int angle)
{
struct vframe_s *new_vf;
struct ppframe_s *pp_vf;
struct display_frame_s input_frame;
struct canvas_s cs0, cs1, cs2, cd, cm;
int t, l, w, h;
unsigned char switch_flag = _3d_process.switch_flag;
int x_offset = 0, dir = 0;
int canvas_width = ppmgr_device.canvas_width;
int canvas_height = ppmgr_device.canvas_height;
int scale_down = get_ppmgr_scaledown() + 1;
int pic_struct = 0;
new_vf = vfq_pop(&q_free);
if (_3d_process._2d_3d_control ==
PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_LEFT_MOVE) {
x_offset = _3d_process._2d_3d_control_value;
} else if (_3d_process._2d_3d_control
== PPMGR_3D_PROCESS_2D_TO_3D_CONTROL_RIGHT_MOVE) {
x_offset = _3d_process._2d_3d_control_value;
dir = 1;
} else {
x_offset = 0;
}
if (unlikely((!new_vf) || (!vf)))
return;
/*int interlace_mode = vf->type & VIDTYPE_TYPEMASK;*/
pp_vf = to_ppframe(new_vf);
pp_vf->dec_frame = NULL;
new_vf->ratio_control = ((scale_down > 1) ?
DISP_RATIO_FORCE_FULL_STRETCH :
DISP_RATIO_FORCE_NORMALWIDE)
| DISP_RATIO_FORCECONFIG;
new_vf->duration = vf->duration;
new_vf->duration_pulldown = vf->duration_pulldown;
new_vf->pts = vf->pts;
if (ppmgr_device.disp_width > ppmgr_device.disp_height)
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD;
else
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD | VIDTYPE_VSCALE_DISABLE;
new_vf->canvas0Addr = new_vf->canvas1Addr = index2canvas(pp_vf->index);
get_input_frame(vf, &input_frame);
new_vf->width = ppmgr_device.disp_width;
new_vf->height = ppmgr_device.disp_height;
if (ppmgr_3d_clear_count > 0) {
/*clear rect*/
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->src_planes[0].addr = cd.addr;
ge2d_config->src_planes[0].w = cd.width;
ge2d_config->src_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = canvas_width;
ge2d_config->src_para.height = canvas_height;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
ppmgr_vf_put_dec(vf);
vfq_push(&q_free, new_vf);
return;
}
fillrect(context, 0, 0, canvas_width, canvas_height,
0x008080ff);
ppmgr_3d_clear_count--;
}
if (vf->type & VIDTYPE_MVC)
pic_struct = (GE2D_FORMAT_M24_YUV420T & (3 << 3));
else
pic_struct = 0;
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(mask_canvas_index, &cm);
ge2d_config->src2_planes[0].addr = cm.addr;
ge2d_config->src2_planes[0].w = cm.width;
ge2d_config->src2_planes[0].h = cm.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_key.key_enable = 1;
ge2d_config->src2_key.key_mask = 0x00ffffff;
ge2d_config->src2_key.key_mode = (switch_flag) ? 1 : 0;
ge2d_config->src2_key.key_color = 0xff000000;
ge2d_config->src2_para.canvas_index = mask_canvas_index;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src2_para.format = GE2D_FORMAT_S8_Y;
ge2d_config->src2_para.fill_color_en = 0;
ge2d_config->src2_para.fill_mode = 0;
ge2d_config->src2_para.x_rev = 0;
ge2d_config->src2_para.y_rev = 0;
ge2d_config->src2_para.color = 0x00808000;
ge2d_config->src2_para.top = 0;
ge2d_config->src2_para.left = 0;
ge2d_config->src2_para.width = canvas_width;
ge2d_config->src2_para.height = canvas_height;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
/* printk("--first frame: %d, %d, %d, %d.out put:%d,
* %d, %d, %d. frame size: %d, %d.\n",
*/
/* input_frame.content_left, input_frame.content_top,
* input_frame.content_width, input_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
}
}
if (is_vertical_sample_enable(vf)) {
blend(context,
input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
input_frame.content_height / 2,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
} else {
blend(context,
input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
(pic_struct) ?
(input_frame.content_height / 2) :
input_frame.content_height,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
}
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(mask_canvas_index, &cm);
ge2d_config->src2_planes[0].addr = cm.addr;
ge2d_config->src2_planes[0].w = cm.width;
ge2d_config->src2_planes[0].h = cm.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_key.key_enable = 1;
ge2d_config->src2_key.key_mask = 0x00ffffff;
ge2d_config->src2_key.key_mode = (switch_flag) ? 0 : 1;
ge2d_config->src2_key.key_color = 0xff000000;
ge2d_config->src2_para.canvas_index = mask_canvas_index;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src2_para.format = GE2D_FORMAT_S8_Y;
ge2d_config->src2_para.fill_color_en = 0;
ge2d_config->src2_para.fill_mode = 0;
ge2d_config->src2_para.x_rev = 0;
ge2d_config->src2_para.y_rev = 0;
ge2d_config->src2_para.color = 0x00808000;
ge2d_config->src2_para.top = 0;
ge2d_config->src2_para.left = 0;
ge2d_config->src2_para.width = canvas_width;
ge2d_config->src2_para.height = canvas_height;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (x_offset) {
if (angle & 1) {
int dst_h = 0;
if (dir) { /*move down*/
if ((t + x_offset + h) <= new_vf->height) {
if (angle == 3) {
t = t - x_offset;
t &= ~1;
} else {
t = t + x_offset;
t &= ~1;
}
} else if ((t + x_offset) < new_vf->height) {
t = t + x_offset;
t &= ~1;
dst_h = new_vf->height - t;
input_frame.content_width =
((((input_frame.content_width
* dst_h)
<< 8) + 0x80) / h)
>> 8;
h = dst_h;
if (angle == 3)
t = 0;
} else {
PPMGR3D_ERR(
"++2d->3d error, out of range1.\n");
}
} else {/*move up*/
if (t >= x_offset) { /*only pan*/
if (angle == 3) {
t = t + x_offset;
t &= ~1;
} else {
t = t - x_offset;
t &= ~1;
}
} else if ((t + h) > x_offset) { /*need cut*/
int src_w = 0, src_l = 0;
t = 0;
dst_h = h + t - x_offset;
src_w = ((((input_frame.content_width
* dst_h)
<< 8)
+ 0x80)
/ h)
>> 8;
h = dst_h;
src_l =
input_frame.content_left
+ input_frame.content_width
- src_w;
src_l &= ~1;
input_frame.content_width =
input_frame.content_width
+ input_frame.content_left
- src_l;
input_frame.content_left = src_l;
if (angle == 3)
t = t + x_offset;
} else {
PPMGR3D_ERR(
"++2d->3d error,out of range2.\n");
}
}
} else {
int dst_w = 0;
if (dir) { /*move right*/
if ((l + x_offset + w) <= new_vf->width) {
if (angle == 2) {
l = l - x_offset;
l &= ~1;
} else {
l = l + x_offset;
l &= ~1;
}
} else if ((l + x_offset) < new_vf->width) {
l = l + x_offset;
l &= ~1;
dst_w = new_vf->width - l;
input_frame.content_width =
((((input_frame.content_width
* dst_w) << 8) + 0x80) / w)
>> 8;
w = dst_w;
if (angle == 2)
l = 0;
} else {
PPMGR3D_ERR(
"++2d->3d error, out of range1.\n");
}
} else {/*move left*/
if (l >= x_offset) { /*only pan*/
if (angle == 2) {
l = l + x_offset;
l &= ~1;
} else {
l = l - x_offset;
l &= ~1;
}
} else if ((l + w) > x_offset) { /*need cut*/
int src_w = 0, src_l = 0;
l = 0;
dst_w = w + l - x_offset;
src_w = ((((input_frame.content_width
* dst_w)
<< 8)
+ 0x80)
/ w)
>> 8;
w = dst_w;
src_l =
input_frame.content_left
+ input_frame.content_width
- src_w;
src_l &= ~1;
input_frame.content_width =
input_frame.content_width
+ input_frame.content_left
- src_l;
input_frame.content_left = src_l;
if (angle == 2)
l = l + x_offset;
} else {
PPMGR3D_ERR(
"++2d->3d error, out of range2.\n");
}
}
}
}
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
new_vf->width = new_vf->width / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
new_vf->height = new_vf->height / scale_down;
}
}
if (is_vertical_sample_enable(vf)) {
blend(context,
input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
input_frame.content_height / 2,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
} else {
blend(context,
input_frame.content_left,
input_frame.content_top,
input_frame.content_width,
(pic_struct) ?
(input_frame.content_height / 2) :
input_frame.content_height,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
}
/* printk("--second frame: %d, %d, %d, %d.out put:
* %d, %d, %d, %d. frame size: %d, %d.\n",
*/
/* input_frame.content_left, input_frame.content_top,
* input_frame.content_width, input_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
ppmgr_vf_put_dec(vf);
vfq_push(&q_ready, new_vf);
}
/* for 3D video input processing
* 1. output window should 1:1 as video layer size
* 2. must adjust GE2D operation according with the frame ratio ,
* then clear ratio control flag
* 3. need generate two buffer from source frame
* 4. input format should be YUV422 , output format should be YUV444
*/
/* for 90 degree and 270 degree, use interlace mode to output mix data.*/
void process_3d_ex(struct vframe_s *vf, struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config,
unsigned int angle)
{
struct vframe_s *new_vf;
struct ppframe_s *pp_vf;
struct display_frame_s l_frame, r_frame;
struct canvas_s cs0, cs1, cs2, cd;
int t, l, w, h;
unsigned char switch_flag = _3d_process.switch_flag;
int canvas_width = ppmgr_device.canvas_width;
int canvas_height = ppmgr_device.canvas_height;
int scale_down = get_ppmgr_scaledown() + 1;
int pic_struct = 0;
new_vf = vfq_pop(&q_free);
if (unlikely((!new_vf) || (!vf)))
return;
/*int interlace_mode = vf->type & VIDTYPE_TYPEMASK;*/
pp_vf = to_ppframe(new_vf);
pp_vf->dec_frame = NULL;
new_vf->ratio_control = ((scale_down > 1) ?
DISP_RATIO_FORCE_FULL_STRETCH :
DISP_RATIO_FORCE_NORMALWIDE)
| DISP_RATIO_FORCECONFIG;
new_vf->duration = vf->duration;
new_vf->duration_pulldown = vf->duration_pulldown;
new_vf->pts = vf->pts;
if (ppmgr_device.disp_width > ppmgr_device.disp_height)
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD;
else
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD | VIDTYPE_VSCALE_DISABLE;
new_vf->canvas0Addr = new_vf->canvas1Addr = index2canvas(pp_vf->index);
/*get_input_frame(vf, &input_frame);*/
get_input_l_frame(vf, &l_frame);
get_input_r_frame(vf, &r_frame);
new_vf->width = ppmgr_device.disp_width;
new_vf->height = ppmgr_device.disp_height;
if (ppmgr_3d_clear_count > 0) {
/*clear rect*/
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->src_planes[0].addr = cd.addr;
ge2d_config->src_planes[0].w = cd.width;
ge2d_config->src_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = canvas_width;
ge2d_config->src_para.height = canvas_height;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
ppmgr_vf_put_dec(vf);
vfq_push(&q_free, new_vf);
return;
}
fillrect(context, 0, 0, canvas_width, canvas_height,
0x008080ff);
ppmgr_3d_clear_count--;
}
if (vf->type & VIDTYPE_MVC)
pic_struct = (GE2D_FORMAT_M24_YUV420T & (3 << 3));
else
pic_struct = 0;
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444
| (switch_flag ?
(GE2D_FORMAT_M24_YUV420B & (3 << 3)) :
(GE2D_FORMAT_M24_YUV420T & (3 << 3)));
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height >> 1;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(
vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
}
}
/* printk("--l frame ex: %d, %d, %d, %d.out put:%d,
* %d, %d, %d. frame size: %d, %d.\n",
*/
/* l_frame.content_left, l_frame.content_top,
* l_frame.content_width, l_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
if (is_vertical_sample_enable(vf)) {
stretchblt_noalpha(context, l_frame.content_left,
l_frame.content_top,
l_frame.content_width,
l_frame.content_height / 2, l, t / 2, w,
h / 2);
} else {
stretchblt_noalpha(
context,
l_frame.content_left,
l_frame.content_top,
l_frame.content_width,
(pic_struct) ?
(l_frame.content_height / 2) :
l_frame.content_height,
l, t / 2, w, h / 2);
}
if (vf->type & VIDTYPE_MVC)
pic_struct = (GE2D_FORMAT_M24_YUV420B & (3 << 3));
else
pic_struct = 0;
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas1Addr & 0xff, &cs0);
canvas_read((vf->canvas1Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas1Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas1Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444
| (switch_flag ?
(GE2D_FORMAT_M24_YUV420T & (3 << 3)) :
(GE2D_FORMAT_M24_YUV420B & (3 << 3)));
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height >> 1;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
new_vf->width = new_vf->width / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
new_vf->height = new_vf->height / scale_down;
}
}
/* printk("--r frame ex: %d, %d, %d, %d.out put:%d,
* %d, %d, %d. frame size: %d, %d.\n",
*/
/* r_frame.content_left, r_frame.content_top,
* r_frame.content_width, r_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
if (is_vertical_sample_enable(vf)) {
stretchblt_noalpha(context, r_frame.content_left,
r_frame.content_top,
r_frame.content_width,
r_frame.content_height / 2, l, t / 2, w,
h / 2);
} else {
stretchblt_noalpha(
context,
r_frame.content_left,
r_frame.content_top,
r_frame.content_width,
(pic_struct) ?
(r_frame.content_height / 2) :
r_frame.content_height,
l, t / 2, w, h / 2);
}
ppmgr_vf_put_dec(vf);
vfq_push(&q_ready, new_vf);
}
void process_3d(struct vframe_s *vf, struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config, unsigned int angle)
{
struct vframe_s *new_vf;
struct ppframe_s *pp_vf;
struct display_frame_s l_frame, r_frame;
struct canvas_s cs0, cs1, cs2, cd, cm;
int t, l, w, h;
unsigned char switch_flag = _3d_process.switch_flag;
int canvas_width = ppmgr_device.canvas_width;
int canvas_height = ppmgr_device.canvas_height;
int scale_down = get_ppmgr_scaledown() + 1;
int pic_struct = 0;
new_vf = vfq_pop(&q_free);
if (unlikely((!new_vf) || (!vf)))
return;
/*int interlace_mode = vf->type & VIDTYPE_TYPEMASK;*/
pp_vf = to_ppframe(new_vf);
pp_vf->dec_frame = NULL;
new_vf->ratio_control = ((scale_down > 1) ?
DISP_RATIO_FORCE_FULL_STRETCH :
DISP_RATIO_FORCE_NORMALWIDE)
| DISP_RATIO_FORCECONFIG;
new_vf->duration = vf->duration;
new_vf->duration_pulldown = vf->duration_pulldown;
new_vf->pts = vf->pts;
if (ppmgr_device.disp_width > ppmgr_device.disp_height)
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD;
else
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD | VIDTYPE_VSCALE_DISABLE;
new_vf->canvas0Addr = new_vf->canvas1Addr = index2canvas(pp_vf->index);
/*get_input_frame(vf, &input_frame);*/
get_input_l_frame(vf, &l_frame);
get_input_r_frame(vf, &r_frame);
new_vf->width = ppmgr_device.disp_width;
new_vf->height = ppmgr_device.disp_height;
if (ppmgr_3d_clear_count > 0) {
/*clear rect*/
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->src_planes[0].addr = cd.addr;
ge2d_config->src_planes[0].w = cd.width;
ge2d_config->src_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = canvas_width;
ge2d_config->src_para.height = canvas_height;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
ppmgr_vf_put_dec(vf);
vfq_push(&q_free, new_vf);
return;
}
fillrect(context, 0, 0, canvas_width, canvas_height,
0x008080ff);
ppmgr_3d_clear_count--;
}
/* data operating. */
if (vf->type & VIDTYPE_MVC)
pic_struct = (GE2D_FORMAT_M24_YUV420T & (3 << 3));
else
pic_struct = 0;
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(mask_canvas_index, &cm);
ge2d_config->src2_planes[0].addr = cm.addr;
ge2d_config->src2_planes[0].w = cm.width;
ge2d_config->src2_planes[0].h = cm.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_key.key_enable = 1;
ge2d_config->src2_key.key_mask = 0x00ffffff;
ge2d_config->src2_key.key_mode = (switch_flag) ? 1 : 0;
ge2d_config->src2_key.key_color = 0xff000000;
ge2d_config->src2_para.canvas_index = mask_canvas_index;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src2_para.format = GE2D_FORMAT_S8_Y;
ge2d_config->src2_para.fill_color_en = 0;
ge2d_config->src2_para.fill_mode = 0;
ge2d_config->src2_para.x_rev = 0;
ge2d_config->src2_para.y_rev = 0;
ge2d_config->src2_para.color = 0x00808000;
ge2d_config->src2_para.top = 0;
ge2d_config->src2_para.left = 0;
ge2d_config->src2_para.width = canvas_width;
ge2d_config->src2_para.height = canvas_height;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(
vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
}
}
/* printk("--l frame: %d, %d, %d, %d.out put:%d,
* %d, %d, %d. frame size: %d, %d.\n",
*/
/* l_frame.content_left, l_frame.content_top,
* l_frame.content_width, l_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
if (is_vertical_sample_enable(vf)) {
blend(context,
l_frame.content_left,
l_frame.content_top,
l_frame.content_width,
l_frame.content_height / 2,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
} else {
blend(context,
l_frame.content_left,
l_frame.content_top,
l_frame.content_width,
(pic_struct) ?
(l_frame.content_height / 2) :
l_frame.content_height,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
}
if (vf->type & VIDTYPE_MVC)
pic_struct = (GE2D_FORMAT_M24_YUV420B & (3 << 3));
else
pic_struct = 0;
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(vf->canvas1Addr & 0xff, &cs0);
canvas_read((vf->canvas1Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas1Addr >> 16) & 0xff, &cs2);
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(mask_canvas_index, &cm);
ge2d_config->src2_planes[0].addr = cm.addr;
ge2d_config->src2_planes[0].w = cm.width;
ge2d_config->src2_planes[0].h = cm.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_key.key_color = 0;
ge2d_config->src_para.canvas_index = vf->canvas1Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_key.key_enable = 1;
ge2d_config->src2_key.key_mask = 0x00ffffff;
ge2d_config->src2_key.key_mode = (switch_flag) ? 0 : 1;
ge2d_config->src2_key.key_color = 0xff000000;
ge2d_config->src2_para.canvas_index = mask_canvas_index;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src2_para.format = GE2D_FORMAT_S8_Y;
ge2d_config->src2_para.fill_color_en = 0;
ge2d_config->src2_para.fill_mode = 0;
ge2d_config->src2_para.x_rev = 0;
ge2d_config->src2_para.y_rev = 0;
ge2d_config->src2_para.color = 0x00808000;
ge2d_config->src2_para.top = 0;
ge2d_config->src2_para.left = 0;
ge2d_config->src2_para.width = canvas_width;
ge2d_config->src2_para.height = canvas_height;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(
vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (scale_down > 1) {
if (angle & 1) {
l =
((new_vf->width / scale_down)
- (w / scale_down)) / 2;
w = w / scale_down;
new_vf->width = new_vf->width / scale_down;
} else {
t =
((new_vf->height / scale_down)
- (h / scale_down)) / 2;
h = h / scale_down;
new_vf->height = new_vf->height / scale_down;
}
}
/* printk("--r frame: %d, %d, %d, %d.out put:%d, %d, %d, %d.
* frame size: %d, %d.\n",
*/
/* r_frame.content_left, r_frame.content_top,
* r_frame.content_width, r_frame.content_height,
*/
/* l, t, w, h, new_vf->width, new_vf->height);*/
if (is_vertical_sample_enable(vf)) {
blend(context,
r_frame.content_left,
r_frame.content_top,
r_frame.content_width,
r_frame.content_height / 2,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
} else {
blend(context,
r_frame.content_left,
r_frame.content_top,
r_frame.content_width,
(pic_struct) ?
(r_frame.content_height / 2) :
r_frame.content_height,
l,
t,
w,
h,
l,
t,
w,
h,
blendop(OPERATION_ADD, COLOR_FACTOR_ONE,
COLOR_FACTOR_ZERO,
OPERATION_ADD,
ALPHA_FACTOR_ZERO, ALPHA_FACTOR_ZERO));
}
ppmgr_vf_put_dec(vf);
vfq_push(&q_ready, new_vf);
}
/* void process_bt(struct vframe_s *vf, struct ge2d_context_s
* *context, struct config_para_ex_s* ge2d_config, int swith_flag)
*/
/*{*/
/**/
/*}*/
/* static void process_field_depth(struct vframe_s *vf,
* struct ge2d_context_s *context, struct config_para_ex_s* ge2d_config)
*/
/*{*/
/**/
/*}*/
void process_3d_to_2d(struct vframe_s *vf, struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config)
{
struct vframe_s *new_vf;
struct ppframe_s *pp_vf;
/*int index;*/
/*struct display_frame_s input_frame;*/
struct display_frame_s src_frame;
struct canvas_s cs0, cs1, cs2, cd;
int t, l, w, h;
unsigned char l_r = _3d_process._3d_to_2d_use_frame;
unsigned int angle = get_ppmgr_direction3d();/*_3d_process.direction;*/
int canvas_width = ppmgr_device.canvas_width;
int canvas_height = ppmgr_device.canvas_height;
int scale_down = get_ppmgr_scaledown() + 1;
int pic_struct = 0;
new_vf = vfq_pop(&q_free);
if (unlikely((!new_vf) || (!vf)))
return;
/*int interlace_mode = vf->type & VIDTYPE_TYPEMASK;*/
pp_vf = to_ppframe(new_vf);
pp_vf->dec_frame = NULL;
new_vf->ratio_control = ((scale_down > 1) ?
DISP_RATIO_FORCE_FULL_STRETCH :
DISP_RATIO_FORCE_NORMALWIDE)
| DISP_RATIO_FORCECONFIG;
new_vf->duration = vf->duration;
new_vf->duration_pulldown = vf->duration_pulldown;
new_vf->pts = vf->pts;
new_vf->type = VIDTYPE_VIU_444 | VIDTYPE_VIU_SINGLE_PLANE
| VIDTYPE_VIU_FIELD;
new_vf->canvas0Addr = new_vf->canvas1Addr = index2canvas(pp_vf->index);
/*get_input_frame(vf, &input_frame);*/
if (!l_r)
get_input_l_frame(vf, &src_frame);
else
get_input_r_frame(vf, &src_frame);
new_vf->width = ppmgr_device.disp_width;
new_vf->height = ppmgr_device.disp_height;
if (ppmgr_3d_clear_count > 0) {
/*clear rect*/
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->src_planes[0].addr = cd.addr;
ge2d_config->src_planes[0].w = cd.width;
ge2d_config->src_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = canvas_width;
ge2d_config->src_para.height = canvas_height;
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
ppmgr_vf_put_dec(vf);
vfq_push(&q_free, new_vf);
return;
}
fillrect(context, 0, 0, canvas_width, canvas_height,
0x008080ff);
ppmgr_3d_clear_count--;
}
if (vf->type & VIDTYPE_MVC) {
pic_struct =
(l_r) ?
(GE2D_FORMAT_M24_YUV420B & (3 << 3)) :
(GE2D_FORMAT_M24_YUV420T & (3 << 3));
} else {
pic_struct = 0;
}
/* data operating. */
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;/*0x000000ff;*/
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;/*0xff;*/
ge2d_config->dst_xy_swap = 0;
if (l_r) {
canvas_read(vf->canvas1Addr & 0xff, &cs0);
canvas_read((vf->canvas1Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas1Addr >> 16) & 0xff, &cs2);
} else {
canvas_read(vf->canvas0Addr & 0xff, &cs0);
canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1);
canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2);
}
ge2d_config->src_planes[0].addr = cs0.addr;
ge2d_config->src_planes[0].w = cs0.width;
ge2d_config->src_planes[0].h = cs0.height;
ge2d_config->src_planes[1].addr = cs1.addr;
ge2d_config->src_planes[1].w = cs1.width;
ge2d_config->src_planes[1].h = cs1.height;
ge2d_config->src_planes[2].addr = cs2.addr;
ge2d_config->src_planes[2].w = cs2.width;
ge2d_config->src_planes[2].h = cs2.height;
canvas_read(new_vf->canvas0Addr & 0xff, &cd);
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->src_key.key_enable = 0;
ge2d_config->src_key.key_mask = 0;
ge2d_config->src_key.key_mode = 0;
ge2d_config->src_para.canvas_index =
(l_r) ? vf->canvas1Addr : vf->canvas0Addr;
ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->src_para.format = get_input_format(vf) | pic_struct;
ge2d_config->src_para.fill_color_en = 0;
ge2d_config->src_para.fill_mode = 0;
ge2d_config->src_para.x_rev = 0;
ge2d_config->src_para.y_rev = 0;
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
if (is_vertical_sample_enable(vf)) {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height = vf->height / 2;
} else {
ge2d_config->src_para.width = vf->width;
ge2d_config->src_para.height =
(pic_struct) ? (vf->height / 2) : vf->height;
}
ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.canvas_index = new_vf->canvas0Addr;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.x_rev = 0;
ge2d_config->dst_para.y_rev = 0;
ge2d_config->dst_para.color = 0;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = canvas_width;
ge2d_config->dst_para.height = canvas_height;
if (angle == 1) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.x_rev = 1;
} else if (angle == 2) {
ge2d_config->dst_para.x_rev = 1;
ge2d_config->dst_para.y_rev = 1;
} else if (angle == 3) {
ge2d_config->dst_xy_swap = 1;
ge2d_config->dst_para.y_rev = 1;
}
if (ge2d_context_config_ex(context, ge2d_config) < 0) {
PPMGR3D_ERR("++ge2d configing error.\n");
return;
}
get_output_rect_after_ratio(vf, &t, &l, &w, &h, vf->width, vf->height,
new_vf->width, new_vf->height, angle);
if (scale_down > 1) {
t = ((new_vf->height / scale_down) - (h / scale_down)) / 2;
h = h / scale_down;
new_vf->height = new_vf->height / scale_down;
l = ((new_vf->width / scale_down) - (w / scale_down)) / 2;
w = w / scale_down;
new_vf->width = new_vf->width / scale_down;
}
if (is_vertical_sample_enable(vf)) {
stretchblt_noalpha(context, src_frame.content_left,
src_frame.content_top,
src_frame.content_width,
src_frame.content_height / 2, l, t, w,
h);
} else {
stretchblt_noalpha(
context,
src_frame.content_left,
src_frame.content_top,
src_frame.content_width,
(pic_struct) ?
(src_frame.content_height / 2) :
src_frame.content_height,
l, t, w, h);
}
ppmgr_vf_put_dec(vf);
vfq_push(&q_ready, new_vf);
}
/********************************************************************/
void ppmgr_vf_3d(struct vframe_s *vf, struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config)
{
struct display_frame_s input_frame;
struct display_frame_s l_frame, r_frame;
struct canvas_s cd;
int cur_angle = 0;
int process_type = get_mid_process_type(vf);
cur_process_type = process_type;
get_input_frame(vf, &input_frame);
get_input_l_frame(vf, &l_frame);
get_input_r_frame(vf, &r_frame);
canvas_read(vf->canvas0Addr & 0xff, &cd);
if (vf->type & VIDTYPE_VIU_422)
cd.width >>= 1;
if (((input_frame.content_left + input_frame.content_width) > cd.width)
|| ((input_frame
.content_top
+ input_frame
.content_height)
> cd
.height)
|| ((input_frame.frame_left + input_frame.frame_width) > cd
.width)
|| ((input_frame.frame_top + input_frame.frame_height) > cd
.height)) {
ppmgr_vf_put_dec(vf);
PPMGR3D_WARN("case 1: vdin canvas setting is");
PPMGR3D_WARN(" not compatible with vframe!!!\n");
return;
}
if (((l_frame.content_left + l_frame.content_width) > cd.width)
|| ((l_frame
.content_top
+ l_frame
.content_height)
> cd
.height)
|| ((l_frame.frame_left + l_frame.frame_width) > cd.width)
|| ((l_frame.frame_top + l_frame.frame_height) > cd.height)) {
ppmgr_vf_put_dec(vf);
PPMGR3D_WARN("case 2: vdin canvas setting is");
PPMGR3D_WARN(" not compatible with vframe!!!\n");
return;
}
if (((r_frame.content_left + r_frame.content_width) > cd.width)
|| ((r_frame
.content_top
+ r_frame
.content_height)
> cd
.height)
|| ((r_frame.frame_left + r_frame.frame_width) > cd.width)
|| ((r_frame.frame_top + r_frame.frame_height) > cd.height)) {
ppmgr_vf_put_dec(vf);
PPMGR3D_WARN("case 3:vdin canvas setting is");
PPMGR3D_WARN(" not compatible with vframe!!!\n");
return;
}
cur_angle = get_ppmgr_direction3d();/*_3d_process.direction;*/
switch (process_type) {
case TYPE_NONE:
/* printk("process none type\n");*/
process_none(vf, context, ge2d_config);
break;
case TYPE_2D_TO_3D:
/* printk("process 2d to 3d type\n");*/
/*if (_3d_process._2d_to_3d_type == PPMGR_3D_PROCESS_2D_TO_3D_NORMAL)*/
if (cur_angle & 1)
process_2d_to_3d_ex(vf, context, ge2d_config,
cur_angle);
else
process_2d_to_3d(vf, context, ge2d_config, cur_angle);
/*else*/
/* process_field_depth(vf, context, ge2d_config);*/
break;
case TYPE_3D_LR:
case TYPE_3D_TB:
/*printk("process 3d type\n");*/
if (cur_angle & 1)
process_3d_ex(vf, context, ge2d_config, cur_angle);
else
process_3d(vf, context, ge2d_config, cur_angle);
break;
case TYPE_3D_TO_2D_LR:
case TYPE_3D_TO_2D_TB:
/* printk("process 3d to 2d type\n");*/
process_3d_to_2d(vf, context, ge2d_config);
break;
default:
break;
}
}
int Init3DBuff(int canvas_id)
{
void __iomem *mask_start = NULL;
unsigned char mask = 0xff;
struct canvas_s canvas_mask;
int k = 0;
unsigned char *buff = NULL;
mask_canvas_index = canvas_id;
canvas_read(mask_canvas_index, &canvas_mask);
mask_start = ioremap_wc(canvas_mask.addr,
canvas_mask.width * canvas_mask.height);
buff = (unsigned char *)mask_start;
while (k < canvas_mask.width * canvas_mask.height) {
buff[k] = mask;
mask = ~mask;
k++;
}
iounmap(mask_start);
return 0;
}