vo_zr.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 827 行 · 第 1/2 页
C
827 行
zr->image = malloc(2*zr->size); /* this buffer allows for YUV422 data, * so it is a bit too big for YUV420 */ if (!zr->image) { mp_msg(MSGT_VO, MSGL_ERR, "zr: Memory exhausted\n"); return 1; } /* and make sure that the borders are _really_ black */ switch (format) { case IMGFMT_YV12: memset(zr->image, 0, zr->size); memset(zr->image + zr->size, 0x80, zr->size/4); memset(zr->image + 3*zr->size/2, 0x80, zr->size/4); zr->y_data = zr->image; zr->u_data = zr->image + zr->size; zr->v_data = zr->image + 3*zr->size/2; zr->y_stride = zr->image_width; zr->u_stride = zr->image_width/2; zr->v_stride = zr->image_width/2; zr->j = jpeg_enc_init(zr->image_width/zr->hdec, zr->image_height/zr->fields, zr->hdec, zr->y_stride*zr->fields, zr->hdec, zr->u_stride*zr->fields, zr->hdec, zr->v_stride*zr->fields, 1, zr->quality, zr->bw); break; case IMGFMT_YUY2: for (tmp = 0; tmp < 2*zr->size; tmp+=4) { zr->image[tmp] = 0; zr->image[tmp+1] = 0x80; zr->image[tmp+2] = 0; zr->image[tmp+3] = 0x80; } zr->y_data = zr->image; zr->u_data = zr->image + 1; zr->v_data = zr->image + 3; zr->y_stride = 2*zr->image_width; zr->u_stride = 2*zr->image_width; zr->v_stride = 2*zr->image_width; zr->j = jpeg_enc_init(zr->image_width/zr->hdec, zr->image_height/zr->fields, zr->hdec*2, zr->y_stride*zr->fields, zr->hdec*4, zr->u_stride*zr->fields, zr->hdec*4, zr->v_stride*zr->fields, 0, zr->quality, zr->bw); break; default: mp_msg(MSGT_VO, MSGL_FATAL, "zr: internal inconsistency in vo_zr\n"); } if (zr->j == NULL) { mp_msg(MSGT_VO, MSGL_ERR, "zr: error initializing the jpeg encoder\n"); return 1; } if (init_zoran(zr, stretchx, stretchy)) { return 1; } } return 0;}static void draw_osd(void) {}static void flip_page (void) { int i, j, k; //FILE *fp; //char filename[100]; /* do we have a free buffer? */ for (j = 0; j < zr_count; j++) { zr_info_t *zr = &zr_info[j]; /* using MJPEG_NBUFFERS here, using the real number of * buffers may give sync issues (real number of buffers * is always sufficient) */ if (zr->queue-zr->synco < MJPEG_NBUFFERS) { zr->frame = zr->queue; } else { if (ioctl(zr->vdes, MJPIOC_SYNC, &zr->zs) < 0) mp_msg(MSGT_VO, MSGL_ERR, "zr: error waiting for buffers to become free\n"); zr->frame = zr->zs.frame; zr->synco++; } k=0; for (i = 0; i < zr->fields; i++) k+=jpeg_enc_frame(zr->j, zr->y_data + i*zr->y_stride, zr->u_data + i*zr->u_stride, zr->v_data + i*zr->v_stride, zr->buf + zr->frame*zr->zrq.size+k); if (k > zr->zrq.size) mp_msg(MSGT_VO, MSGL_WARN, "zr: jpeg image too large for maximum buffer size. Lower the jpeg encoding\nquality or the resolution of the movie.\n"); } /* Warning: Only the first jpeg image contains huffman- and * quantisation tables, so don't expect files other than * test0001.jpg to be readable */ /*sprintf(filename, "test%04d.jpg", framenum); fp = fopen(filename, "w"); if (!fp) exit(1); fwrite(buf+frame*zrq.size, 1, k, fp); fclose(fp);*/ /*fp = fopen("test1.jpg", "r"); fread(buf+frame*zrq.size, 1, 2126, fp); fclose(fp);*/ for (j = 0; j < zr_count; j++) { zr_info_t *zr = &zr_info[j]; if (ioctl(zr->vdes, MJPIOC_QBUF_PLAY, &zr->frame) < 0) mp_msg(MSGT_VO, MSGL_ERR, "zr: error queueing buffer for playback\n"); zr->queue++; } framenum++; return;}static int draw_frame(uint8_t * src[]) { int i, j; char *source, *dest; //printf("draw frame called\n"); for (j = 0; j < zr_count; j++) { zr_info_t *zr = &zr_info[j]; geo_t *g = &zr->g; source = src[0] + 2*g->yoff*zr->vdec*zr->stride + 2*g->xoff; dest = zr->image + 2*zr->off_y; for (i = 0; i < g->height/zr->vdec; i++) { fast_memcpy(dest, source, zr->image_width*2); dest += 2*zr->image_width; source += zr->vdec*zr->stride; } } return 0;}static int query_format(uint32_t format) { if(format==IMGFMT_YV12 || format==IMGFMT_YUY2) return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW; return 0;}static void uninit(void) { int j; mp_msg(MSGT_VO, MSGL_V, "zr: uninit called\n"); for (j = 0; j < zr_count; j++) { jpeg_enc_uninit(zr_info[j].j); uninit_zoran(&zr_info[j]); }}static void check_events(void) {}static int draw_slice(uint8_t *srcimg[], int stride[], int wf, int hf, int xf, int yf) { int i, j, w, h, x, y; /* Apply 'geometry', crop unwanted parts */ uint8_t *dst; //printf("before: w=%d, h=%d, x=%d, y=%d, src0=%p, src1=%p, src2=%p\n", w, h, x, y, srcimg[0], srcimg[1], srcimg[2]); for (j = 0; j < zr_count; j++) { uint8_t *src=srcimg[0]; uint8_t *src1=srcimg[1]; uint8_t *src2=srcimg[2]; zr_info_t *zr = &zr_info[j]; geo_t *g = &zr->g; w = wf; h = hf; x = xf; y = yf; if (x < g->xoff) { src += g->xoff - x; src1 += (g->xoff - x)/2; src2 += (g->xoff - x)/2; w -= g->xoff - x; if (w < 0) break; //return 0; x = 0 /*g.xoff*/; } else { x -= g->xoff; } if (x + w > g->width) { w = g->width - x; if (w < 0) break; //return 0; } if (y < g->yoff) { src += (g->yoff - y)*stride[0]; src1 += ((g->yoff - y)/2)*stride[1]; src2 += ((g->yoff - y)/2)*stride[2]; h -= g->yoff - y; if (h < 0) break; //return 0; y = 0; } else { y -= g->yoff; } if (y + h > g->height) { h = g->height - y; if (h < 0) break; //return 0; } //printf("after: w=%d, h=%d, x=%d, y=%d, src0=%p, src1=%p, src2=%p\n", w, h, x, y, srcimg[0], srcimg[1], srcimg[2]); dst=zr->image + zr->off_y + zr->image_width*(y/zr->vdec)+x; // copy Y: for (i = 0; i < h; i++) { if ((i + x)%zr->vdec == 0) { fast_memcpy(dst,src,w); dst+=zr->image_width; } src+=stride[0]; } if (!zr->bw) { // copy U+V: uint8_t *dst1=zr->image + zr->size + zr->off_c+ (y/(zr->vdec*2))*zr->image_width/2+(x/2); uint8_t *dst2=zr->image + 3*zr->size/2 + zr->off_c + (y/(zr->vdec*2))* zr->image_width/2+(x/2); for (i = 0; i< h/2; i++) { if ((i+x/2)%zr->vdec == 0) { fast_memcpy(dst1,src1,w/2); fast_memcpy(dst2,src2,w/2); dst1+=zr->image_width/2; dst2+=zr->image_width/2; } src1+=stride[1]; src2+=stride[2]; } } } return 0;}/* copied and adapted from vo_aa_parseoption */intvo_zr_parseoption(m_option_t* conf, char *opt, char *param){ /* got an option starting with zr */ zr_info_t *zr = &zr_info[zr_parsing]; int i; /* do WE need it ?, always */ if (!strcasecmp(opt, "zrdev")) { if (param == NULL) return ERR_MISSING_PARAM; //if ((i=getcolor(param))==-1) return ERR_OUT_OF_RANGE; //aaopt_osdcolor=i; free(zr->device); zr->device = malloc(strlen(param)+1); strcpy(zr->device, param); mp_msg(MSGT_VO, MSGL_V, "zr: using device %s\n", zr->device); return 1; } else if (!strcasecmp(opt, "zrbw")) { if (param != NULL) { return ERR_OUT_OF_RANGE; } zr->bw = 1; return 1; } else if (!strcasecmp(opt, "zrfd")) { if (param != NULL) { return ERR_OUT_OF_RANGE; } zr->fd = 1; return 1; } else if (!strcasecmp(opt, "zrcrop")){ geo_t *g = &zr->g; if (g->set == 1) { zr_parsing++; zr_count++; zr = &zr_info[zr_parsing]; g = &zr->g; if (zr_count > 4) { mp_msg(MSGT_VO, MSGL_ERR, "zr: too many simultaneus display devices requested (max. is 4)\n"); return ERR_OUT_OF_RANGE; } } if (param == NULL) return ERR_MISSING_PARAM; if (sscanf(param, "%dx%d+%d+%d", &g->width, &g->height, &g->xoff, &g->yoff) != 4) { g->xoff = 0; g->yoff = 0; if (sscanf(param, "%dx%d", &g->width, &g->height) != 2) { mp_msg(MSGT_VO, MSGL_ERR, "zr: argument to -zrcrop must be of the form 352x288+16+0\n"); return ERR_OUT_OF_RANGE; } } g->set = 1; mp_msg(MSGT_VO, MSGL_V, "zr: cropping %s\n", param); return 1; }else if (!strcasecmp(opt, "zrhdec")) { i = atoi(param); if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE; zr->hdec = i; return 1; }else if (!strcasecmp(opt, "zrvdec")) { i = atoi(param); if (i != 1 && i != 2 && i != 4) return ERR_OUT_OF_RANGE; zr->vdec = i; return 1; }else if (!strcasecmp(opt, "zrxdoff")) { i = atoi(param); zr->xdoff = i; return 1; }else if (!strcasecmp(opt, "zrydoff")) { i = atoi(param); zr->ydoff = i; return 1; }else if (!strcasecmp(opt, "zrquality")) { i = atoi(param); if (i < 1 || i > 20) return ERR_OUT_OF_RANGE; zr->quality = i; return 1; }else if (!strcasecmp(opt, "zrnorm")) { if (param == NULL) return ERR_MISSING_PARAM; if (!strcasecmp(param, "NTSC")) { mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to NTSC\n"); zr->norm = VIDEO_MODE_NTSC; return 1; } else if (!strcasecmp(param, "PAL")) { mp_msg(MSGT_VO, MSGL_V, "zr: Norm set to PAL\n"); zr->norm = VIDEO_MODE_PAL; return 1; } else { return ERR_OUT_OF_RANGE; } }else if (!strcasecmp(opt, "zrhelp")){ printf("Help for -vo zr: Zoran ZR360[56]7/ZR36060 based MJPEG capture/playback cards\n"); printf("\n"); printf("Here are the zr options:\n"); printf( "\n" " -zrcrop specify part of the input image that\n" " you want to see as an x-style geometry string\n" " example: -zrcrop 352x288+16+0\n" " -zrvdec vertical decimation 1, 2 or 4\n" " -zrhdec horizontal decimation 1, 2 or 4\n" " -zrfd decimation is only done if the primitive\n" " hardware upscaler can correct for the decimation,\n" " this switch allows you to see the effects\n" " of too much decimation\n" " -zrbw display in black&white (speed increase)\n" " -zrxdoff x offset from upper-left of TV screen (default is 'centered')\n" " -zrydoff y offset from upper-left of TV screen (default is 'centered')\n" " -zrquality jpeg compression quality [BEST] 1 - 20 [VERY BAD]\n" " -zrdev playback device (example -zrdev /dev/video1)\n" " -zrnorm specify norm PAL/NTSC (default: leave at current setting)\n" "\n" "Cinerama support: additional occurances of -zrcrop activate cinerama mode,\n" "suppose you have a 704x272 movie, two DC10+ cards and two beamers (or tv's),\n" "then you would issue the following command:\n\n" "mplayer -vo zr -zrcrop 352x272+0+0 -zrdev /dev/video0 -zrcrop 352x272+352+0 \\\n" " -zrdev /dev/video1 movie.avi\n\n" "Options appearing after the second -zrcrop apply to the second card, it is\n" "possible to dispay at a different jpeg quality or at different decimations.\n\n" "The parameters -zrxdoff and -zrydoff can be used to align the two images.\n" "The maximum number of zoran cards participating in cinerama is 4, so you can\n" "build a 2x2 vidiwall. (untested for obvious reasons, the setup wit a buz and\n" "a DC10+ (and no beamers) is tested, however)\n" ); exit(0); } return ERR_NOT_AN_OPTION;}void vo_zr_revertoption(m_option_t* opt,char* param) { zr_info_t *zr = &zr_info[1]; zr_count = 1; zr_parsing = 0; if (!strcasecmp(param, "zrdev")) { if(zr->device) free(zr->device); zr->device=NULL; } else if (!strcasecmp(param, "zrbw")) zr->bw=0; else if (!strcasecmp(param, "zrfd")) zr->fd=0; else if (!strcasecmp(param, "zrcrop")) zr->g.set = zr->g.xoff = zr->g.yoff = 0; else if (!strcasecmp(param, "zrhdec")) zr->hdec = 1; else if (!strcasecmp(param, "zrvdec")) zr->vdec = 1; else if (!strcasecmp(param, "zrxdoff")) zr->xdoff = -1; else if (!strcasecmp(param, "zrydoff")) zr->ydoff = -1; else if (!strcasecmp(param, "zrquality")) zr->quality = 2; else if (!strcasecmp(param, "zrnorm")) zr->norm = VIDEO_MODE_AUTO;}static int preinit(const char *arg){ if(arg) { printf("vo_zr: Unknown subdevice: %s\n",arg); return ENOSYS; } return 0;}static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); } return VO_NOTIMPL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?