📄 video.c
字号:
0x12C) | ((DecoderReadByte(card, 0x12E) & 0x07) << 8); // current Start- and End Row right = DecoderReadByte(card, 0x12D) | ((DecoderReadByte(card, 0x12E) & 0x70) << 4); width = (right - left + 1) / 2; // screen width, 2 clocks = 1 pixel if (RMM) DecoderSetByte(card, 0x0F8, 0x01); else DecoderDelByte(card, 0x0F8, 0x01); DecoderWriteByte(card, 0x0EF, 0x08); //if (x>width) { // Is the picture too wide for the screen? // DecoderSetByte(card,0x112,0x40); // Horiz. 2:1 Filter enable // x/=2; //} else { DecoderDelByte(card, 0x112, 0x40); // Horiz. 2:1 Filter disable //} if (1 /*Letterbox */ ) { // Fit to width, reduce height newwidth = (x * vaspy * paspx / (paspy * vaspx)); // width in right aspect ratio if (newwidth <= 360) { // less then about half the screen size? SIF = 1; newwidth *= 2; } else { SIF = 0; } if ((newwidth == 704) || (newwidth == 720)) width = newwidth; // standard sizes? newheight = (y * vaspx * paspy / (paspx * vaspy)) * width / x; factor = newheight * 100 / y; printk(KERN_INFO LOGNAME ": Decoder Open: Display size %d x %d, Picture size %d x %d, Demanded size: %d x %d, factor %d\n", width, height, x, y, newwidth, newheight, factor); // 16:9 Letterbox if ((aspect == 3) || ((aspect == 0) && (((factor >= 65) && (factor <= 80)) || ((factor >= 140) && (factor <= 160))))) { if (SIF) { // height * 1.5, SIF Letterbox if (RMM) return 1; // not supported! height = (y * 3) / 2 - 2; mode = 3; } else { // height * 0.75, 16:9 Letterbox height = (y * 3) / 4 - 2; mode = 8; } // 2.21:1 Letterbox } else if ((aspect == 4) || ((aspect == 0) && (((factor >= 45) && (factor <= 60)) || (SIF && ((factor >= 90) && (factor <= 110)))))) { if (SIF) { // height * 1 height = y; mode = 5; } else { // height / 2 height = y / 2; mode = 11; } // 3:4 aspect ratio } else { if (SIF) { height = y * 2; mode = ((Field && ~RMM) ? 9 : 10); } else if (newwidth > 720) { // picture too wide, scale down to 3/4 height = (y * 3) / 4; mode = 8; } else { height = y; mode = ((Field) ? 7 : 5);// mode=((Field)?5:7); } } width = (x * vaspy * paspx / (paspy * vaspx)) * height / y; if (x < width) { // does the picture needs a horizontal blow-up? DecoderWriteByte(card, 0x115, ((x * 256 + width - 1) / width) & 0xFF); // Horiz.Filter scale, x/width*256, rounded up DecoderSetByte(card, 0x114, 0x02); // Horiz.Filter enable } else if (x == width) { DecoderWriteByte(card, 0x115, 0); // 1:1 scale DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable } else if (x <= 720) { width = x; DecoderWriteByte(card, 0x115, 0); // 1:1 scale DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable } else { // picture is more than twice the screen width. sigh. return 1; } } else { // Pan-Scan, fit height to maximum DecoderSetByte(card, 0x117, 0x40); // pan-scan from bitstream//TODO newwidth = (x * vaspy * paspx / (paspy * vaspx)); // width in right aspect ratio newheight = y; if (newheight <= 288) { // less then about half the screen size? SIF = 1; newheight *= 2; } else { SIF = 0; } if ((newwidth == 704) || (newwidth == 720)) width = newwidth; // standard sizes? //newheight=(y*vaspx*paspy/(paspx*vaspy))*width/x; factor = newheight * 100 / y; printk(KERN_INFO LOGNAME ": Decoder Open: Display size %d x %d, Picture size %d x %d, Demanded size: %d x %d, factor %d\n", width, height, x, y, newwidth, newheight, factor); if (aspect == 3) { // 16:9 Letterbox if (SIF) { // height * 1.5, SIF Letterbox if (RMM) return 1; // not supported! height = (y * 3) / 2; mode = 3; } else { // height * 0.75, 16:9 Letterbox height = (y * 3) / 4; mode = 8; } } else if (aspect == 4) { // 2.21:1 Letterbox if (SIF) { // height * 1 height = y; mode = 5; } else { // height / 2 height = y / 2; mode = 11; } } else if (aspect == 2) { // 3:4 aspect ratio if (SIF) { height = y * 2; mode = ((Field && ~RMM) ? 9 : 10); } else if (newwidth > 720) { // picture too wide, scale down to 3/4 height = (y * 3) / 4; mode = 8; } else { height = y; mode = ((Field) ? 7 : 5);// mode=((Field)?5:7); } } width = (x * vaspy * paspx / (paspy * vaspx)) * height / y; if (x < width) { // does the picture needs a horizontal blow-up? DecoderWriteByte(card, 0x115, ((x * 256 + width - 1) / width) & 0xFF); // Horiz.Filter scale, x/width*256, rounded up DecoderSetByte(card, 0x114, 0x02); // Horiz.Filter enable } else if (x == width) { DecoderWriteByte(card, 0x115, 0); // 1:1 scale DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable } else if (x <= 720) { width = x; DecoderWriteByte(card, 0x115, 0); // 1:1 scale DecoderDelByte(card, 0x114, 0x02); // Horiz.Filter disable } else { // picture is more than twice the screen width. sigh. return 1; } } printk(KERN_INFO LOGNAME ": Decoder Open: Display size %d x %d, Picture size %d x %d Mode: %d\n", width, height, x, y, mode); // calculate new picture start- and end rows and columns height /= 2; // convert back to field height top += ((bottom - top + 1 - height) / 2); if (top < 0) top = 0; bottom = top + height - 1; width *= 2; // convert back to clocks left += ((right - left + 1 - width) / 2); if (left < 0) left = 0; right = left + width - 1; DecoderWriteByte(card, 0x12C, left & 0xFF); // Start- and End Column DecoderWriteByte(card, 0x12D, right & 0xFF); DecoderWriteByte(card, 0x12E, ((right >> 4) & 0x70) | ((left >> 8) & 0x07)); DecoderWriteByte(card, 0x129, top & 0xFF); // Start- and End Row DecoderWriteByte(card, 0x12A, bottom & 0xFF); DecoderWriteByte(card, 0x12b, ((bottom >> 4) & 0x70) | ((top >> 8) & 0x07)); DecoderWriteByte(card, 0x116, ((x + 7) / 8) & 0x7F); // Main Reads per Line // set the new mode DecoderMaskByte(card, 0x114, 0x78, (mode & 0x0F) << 3); MDEBUG(3,": Decoder Open: top/bottom/width / left/right/height / main reads %d/%d/%d / %d/%d/%d / %d\n",top,bottom,width,left,right,height,((x+7)/8)&0x7F); // set the frame store buffers if ((i = DecoderSetFrameBuffers(card, y, 0, RMM))) { MDEBUG(0,": SetFrameBuffers failed for buffer at 0x%03X\n",i); DecoderKillFrameBuffers(card); return 2; } card->lastvattr = 0; card->DecoderOpen = 1; return 0;}// displays a still image, whose pixel data is in luma and chromaint DecoderShowStill(struct cvdv_cards *card, int width, int height, u8 * luma, u8 * chroma){ u16 addr; DecoderOpen(card, width, height, (((width == 320) || (width == 640) || (width == 384) || (width == 768)) ? 1 : 2), ((height < 313) ? 1 : 0), 1, 0); addr = ((DecoderReadWord(card, 0x11D) == DecoderReadWord(card, 0x0E0)) ? 0x0E4 : 0x0E0); // choose invisible frame DRAMWriteByte(card, DecoderReadWord(card, addr) << 5, width * height, luma, 1); DRAMWriteByte(card, DecoderReadWord(card, addr + 2) << 5, width * height / 2, chroma, 1); DecoderStillImageDisplay(card, ((height < 313) ? 2 : 1), DecoderReadByte(card, 0x116) & 0x7F, DecoderReadWord(card, addr), DecoderReadWord(card, addr + 2)); VideoSetBackground(card, 0, 0, 0, 0); // video on black return 0;}// TODO: untested, probably won't work (have to use "main reads per line" instead of width on SIF)int DecoderGetStill(struct cvdv_cards *card, int *width, int *height, u8 * luma, u8 * chroma){ int framebuffer; if (card->DecoderOpen) { //*width=((DecoderReadByte(card,0x12D)|((DecoderReadByte(card,0x12E)&0x70)<<4))-(DecoderReadByte(card,0x12C)|((DecoderReadByte(card,0x12E)&0x07)<<8))+1)/2; // screen width, 2 clocks = 1 pixel *width = DecoderReadByte(card, 0x116) * 8; *height = ((DecoderReadByte (card, 0x12A) | ((DecoderReadByte(card, 0x12B) & 0x70) << 4)) - (DecoderReadByte(card, 0x129) | ((DecoderReadByte(card, 0x12B) & 0x07) << 8)) + 1) * 2; // screen (frame) height if ((luma != NULL) && (chroma != NULL)) { framebuffer = (((DecoderReadByte(card, 0x0EE) & 0x0C) == 1) ? 0x0E4 : 0x0E0); DRAMReadByte(card, DecoderReadWord(card, framebuffer) << 5, (*width) * (*height), luma, 1); DRAMReadByte(card, DecoderReadWord(card, framebuffer + 2) << 5, (*width) * (*height) / 2, chroma, 1); } return 0; } else return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -