zoom.c
来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 444 行
C
444 行
/* Copyright 1997-2003, ESS Technology, Inc. *//* SCCSID @(#)zoom.c 4.10 04/12/05 */ /* * $Log$ */#ifdef ZOOM#include "mvd.h"#include "common.h"#include "memmap.h"#include "util.h"#include "debug.h"#include "display.h"#include "zoom.h"#include "buffer.h"#include "cg.h"#include "vp.h"#include "vcxi.h"#include "play.h"#ifdef VSCALE#include "vscale.h"#endif#include "xport.h"#include "tdm.h"static unsigned int U_zoom_start , V_zoom_start, Y_zoom_start;int save_width1;int FromBtoB;static int zoom_y_offset, zoom_uv_offset;static unsigned int disp_width, disp_height;PRIVATE void get_pic_size(void);#ifdef PLAY20extern int play_state;#endifvoid Zoom_start(){ int i, j, k, m, tmp; int dest_u_start, dest_v_start, dest_y_start; int wY, wUV; DISP_Info *dip, *dipp; unsigned int buffer_size, height; extern int DISP_frame; int compressed = 0; int v_start, u_start, y_start; int width, full_height; extern int scale_dy_Y, scale_dy_UV; DISP_frame = disp_frame; FromBtoB = 0; dip = DISP_info + DISP_frame; full_height = dip->height > 288; wY = dip->wY; wUV = dip->wUV; if (!zoom_y_pos) zoom_y_pos = 2; k = (zoom_y_pos-2)*wY; if (full_height || dip->zUV) { /* E2 or E0 with compressing */ zoom_uv_offset = ((zoom_y_pos-2) * wUV + ((zoom_x_pos * 3) >> 4))>>1; zoom_uv_offset = (zoom_uv_offset+1) / 3 * 3; tmp = zoom_uv_offset % wUV; m = zoom_uv_offset - tmp; if (full_height) { mvd[vid_scn_misc0] &= 0xfffffffe; mvd[vid_scn_misc0] |= 0x6000; zoom_y_offset = (m << 2) + (tmp << 1); } else { if (dip->zY) zoom_y_offset = k + (tmp << 1); else { zoom_y_offset = (zoom_uv_offset/wUV * wY) << 1; zoom_y_offset += ((tmp << 2)/3) << 1; } } } else { /* E0 without compressing */ zoom_y_offset = k + (zoom_x_pos >> 2); zoom_uv_offset = ((k + (zoom_x_pos >> 1)) >> 2); } zoom_y_offset &= 0xfffffffe; zoom_uv_offset += zoom_uv_offset/wUV*wUV; /* this is because U, V buffer is looked like uuuu..vvvv...uuu...vvv.. */ /* When E0 zoom by 2, or E2 zoom by 4, hardware cannot do vscale as Y,U,V wholely. So, we let hardware do Y vscale, and duplicate UV ourselfs by store UV to a temperary buffer, and duplicate the line . We use VBV buffer as temperary buffer to store U and V, with duplicated lines. */ if (zoom_level == 2 || !dip->zY || DISP_frame == 2) { u_start = dip->startU + zoom_uv_offset; /* dword address */ v_start = u_start + dip->wUV; /* dword address */ /* width of each line which needed to be duplicated */ if (zoom_level == 1) /* E0 */ width = (wUV + 1) >> 1; else /* E2 */ width = (wUV + 3) >> 2; height = dip->height >> 2; buffer_size = ((height * width) << 1); zoom_frame = -1; switch (DISP_frame) { case 0: case 1: dipp = DISP_info + 2;#if 0 /* use VBV */ U_zoom_start = dipp->startY;#endif break; case 2: zoom_frame = H_VscaleFrame; if (vcx_scn_vscale != 0x10 #ifdef PLAY20 && play_state != PLAY_STILL_STATE && play_state != PLAY_WAIT_TIME_STATE && !is_slide_show#endif ) { FromBtoB=1; dipp = DISP_info + 2; } else {#ifdef VSCALE if (H_VscaleFrame == 1) dipp = DISP_info + 1; else dipp = DISP_info + 0;#else dipp = DISP_info + 0;#endif }#if 0 /* use VBV */ if (zoom_y_pos >= 76) U_zoom_start = dipp->startY; else U_zoom_start = dipp->startU - buffer_size * 2 ;#endif break; default: U_zoom_start = VBV_start; /* E2 picture, zoom_buffer start */ /* at VBV buffer */ break; }#if 1 /* ZOOM use VBV for temporary UV, for consistency as well as * avoiding UV being overwritten. */ U_zoom_start = VBV_start; #endif V_zoom_start = U_zoom_start + buffer_size; j = 0; m=0; k = (width *3 ) >> 2; for (i = 0; i < (dip->height >> 2); i++) { m = (i * wUV ) << 1; { for (k = 0; k < width; k++) { *(long*) dram(j + width + U_zoom_start) = *(long*) dram(j + U_zoom_start) = *(long*)dram(u_start + m); *(long*) dram(j + width + V_zoom_start) = *(long*) dram(j + V_zoom_start) = *(long*)dram(v_start + m); j++; m++; asm("nop"); asm("nop"); } j += width; } } } /* with VSCALE on, we cannot use DMA_WIDTH2 register , always set DMA_WIDTH0 to 0, and DMA_WIDTH1 to real width. */ DISP_change_zoom(zoom_level); if (zoom_level == 1 && !full_height) mvd[buscon_dma_width1] = wY >> 1;}void zoom_reset(){ extern int disp_frame; extern int save_zoom_level; DISP_do_blank(); /* then do DISP_END_DO_BLANK to bring back screen */ zoom_x_pos = 0; zoom_y_pos = 0; mvd[buscon_dma_scale_type] = BIG_MEM_BIT; mvd[buscon_dma_width1] = save_width1; zoom_level = 0; DISP_change_zoom(zoom_level); if (vcx_scn_vscale != 0x10 && DISP_frame==2 && FromBtoB) { rescaleB(); } disp_frame = DISP_frame; DISP_END_DO_BLANK;}rescaleB(){ resetVscale(); initVscale_Pointer(); VscaleStart = 1; VscaleLastFrame = 0; while (VscaleStart) vscale2();}void zoom_in(void){ extern int VID_decoding_in_progress ;/* If system is not really pause, then ignore zoom_in key */#ifdef PLAY20 if (XPORT_active && play_state == PLAY_NORMAL_STATE) return;#endif get_pic_size(); if (disp_height <= 288#ifdef PLAY20 || is_slide_show || PLAY_e2_in_loop#endif ) { /* For low resolution, only do 2X zoom */ if (zoom_level == 1) return; zoom_level = 1; } else { if (zoom_level == 2) return; zoom_level ++; } if (zoom_level == 1 || zoom_level == 2){ int d_zoom = zoom_level + 1; zoom_x_pos += disp_width >> d_zoom; zoom_y_pos += disp_height >> d_zoom; } save_width1 = mvd[buscon_dma_width1] ; pan(zoom_x_pos, zoom_y_pos); return;}/* right: dir = 0; left: dir = 1; */void zoom_move_h(int dir){ zoom_x_pos += (dir)? -HORZ_OFFSET:HORZ_OFFSET; pan(zoom_x_pos, zoom_y_pos);}/* up: dir = 1; down: dir = 0; */void zoom_move_v(int dir){ int con0, con1; int offset[2] = {VERT_OFFSET, -VERT_OFFSET}; if (dir ) { con1 = (zoom_y_pos >= 76 && zoom_y_pos+offset[dir]<76); } else { con1 = (zoom_y_pos < 76 && zoom_y_pos + VERT_OFFSET>=76); } if ((DISP_frame == 2 && vcx_scn_vscale !=0x10) && con1 ) { zoom_reset_scale(dir); } else { zoom_y_pos += offset[dir]; } pan(zoom_x_pos, zoom_y_pos);}zoom_reset_scale(int up){ int x, y; x = zoom_x_pos; zoom_y_pos += (up)?-VERT_OFFSET:VERT_OFFSET; y = zoom_y_pos; zoom_reset(); zoom_x_pos = x; zoom_y_pos = y; zoom_level = 1;}void zoom_out(){ if (!zoom_level) return; zoom_level --; get_pic_size(); if (zoom_level == 1) { zoom_x_pos -= disp_width >> 3; zoom_y_pos -= disp_height >> 3; } if (!zoom_level) { expect_zoom = 0; zoom_reset(); if (vcx_scn_vscale != 0x10 && DISP_frame==2 && FromBtoB) { rescaleB(); } } else { save_width1 = mvd[buscon_dma_width1] ; pan(zoom_x_pos, zoom_y_pos); }}pan(int x, int y){ Adjust_zoom_XY(x, y); Zoom_start();}Adjust_zoom_XY(int x, int y){ get_pic_size(); if (x < 0) x = 0; if (y < 0) y = 0; { int width = disp_width >> 1; int height = disp_height >> 1; if (zoom_level == 2) { width = (width * 3) >> 1; height = (height * 3) >> 1; } if (x > width) x = width; if (y > height) y = height; } /* zoom_x_pos needs to think of compressed picture or not(3/4), so we must make sure each picture begin at boundary of dword */#if 0 zoom_x_pos = x / 12 * 12;#else zoom_x_pos = x ;#endif zoom_y_pos = y & 0xfffffffe;}void Buscon_zoom(DISP_Info *dip){ int y_start, u_start, v_start; int full_height; int wY, wUV, zY, zUV; int mode0, mode1; wY = dip->wY; wUV = dip->wUV; y_start = dip->startY + zoom_y_offset; u_start = dip->startU + zoom_uv_offset; v_start = u_start + wUV; zY = dip->zY; zUV = dip->zUV; full_height = dip->height > 288; if (zoom_level == 1) { if (zUV < 0) zUV = 0; if (zY < 0) { /* y_wordsize = uv_wordsize*2-1 */ mvd[buscon_dma_deltas_ysc] = 0x200 - (wUV+1); zY = 0; } else mvd[buscon_dma_deltas_ysc] = 0x200 - ((wY + 1) >> 1); mvd[buscon_dma_deltas_usc] = 0x200 - ((wUV + 1) >> 1); mvd[buscon_dma_deltas_vsc] = 0x200 - ((wUV + 1) >> 1); if (full_height) { mode0 = BDMA_WIDTH2; mode1 = BDMA_WIDTH1|BDMA_INC2; } else { mode0 = BDMA_WIDTH1 | BDMA_INC2; mode1 = BDMA_USEDX; u_start = U_zoom_start; v_start = V_zoom_start; } } else { /* zoom_level == 2 */ mvd[buscon_dma_deltas_ysc] = 0x200 - ((wY + 3) >> 2); mvd[buscon_dma_deltas_usc] = 0x200 - ((wUV + 3) >> 2); mvd[buscon_dma_deltas_vsc] = 0x200 - ((wUV + 3) >> 2); mode0 = BDMA_WIDTH2 | BDMA_INC2; mode1 = BDMA_USEDX; u_start = U_zoom_start; v_start = V_zoom_start; } buscon_quick_BF(ysc, y_start, mode0, zY); buscon_quick_BF(usc, u_start, mode1, zUV); buscon_quick_BF(vsc, v_start, mode1, zUV);}/* * Get picture width and height */void get_pic_size(){ DISP_Info *dip; extern int DISP_frame; dip = DISP_info + DISP_frame; if (dip->zY) disp_width = ((dip->wY << 2) / 3 ) << 2; else disp_width = dip->wY << 2; disp_height = dip->height;}void set_zoom(){ if (!zoom_level) { zoom_in(); } else if (zoom_level == 1 &&#ifdef PLAY20 play_state != PLAY_STILL_STATE &&#endif vcx_user_video_stream == 0xe2) { /* Only for high-resulotion, we have two level zoom */ zoom_in(); } else { zoom_reset(); }}#endif /* ZOOM */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?