📄 tvi_bsdbt848.c
字号:
} case TVI_CONTROL_VID_SET_WIDTH: priv->geom.columns = *(int *)arg; if(priv->geom.columns > priv->maxwidth) { priv->geom.columns = priv->maxwidth; } if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorSettingWidth, strerror(errno)); return(0); } return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_WIDTH: *(int *)arg = priv->geom.columns; return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_SET_HEIGHT: priv->geom.rows = *(int *)arg; if(priv->geom.rows > priv->maxheight) { priv->geom.rows = priv->maxheight; } if(priv->geom.rows <= priv->maxheight / 2) { priv->geom.oformat |= METEOR_GEO_EVEN_ONLY; } if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorSettingWidth, strerror(errno)); return(0); } return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_HEIGHT: *(int *)arg = priv->geom.rows; return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_FPS: *(float *)arg = priv->fps; return(TVI_CONTROL_TRUE); /* case TVI_CONTROL_VID_SET_FPS: priv->fps = *(int *)arg; if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORSFPS", strerror(errno)); return(0); } return(TVI_CONTROL_TRUE); */ case TVI_CONTROL_VID_CHK_WIDTH: case TVI_CONTROL_VID_CHK_HEIGHT: return(TVI_CONTROL_TRUE); case TVI_CONTROL_IMMEDIATE: priv->immediatemode = TRUE; return(TVI_CONTROL_TRUE); } return(TVI_CONTROL_UNKNOWN);}static int init(priv_t *priv){int marg;int count;u_short tmp_fps;G_private = priv; /* Oooh, sick *//* Video Configuration */priv->videoready = TRUE;priv->immediatemode = FALSE;priv->iformat = METEOR_FMT_PAL;priv->maxheight = PAL_HEIGHT;priv->maxwidth = PAL_WIDTH;priv->maxfps = PAL_FPS;priv->source = METEOR_INPUT_DEV0;priv->fps = priv->maxfps;priv->starttime=0;priv->curpaintframe=0;priv->curbufframe=0;priv->geom.columns = priv->maxwidth;priv->geom.rows = priv->maxheight;priv->geom.frames = 1;priv->geom.oformat = METEOR_GEO_YUV_PACKED;priv->btfd = open(priv->btdev, O_RDONLY);if(priv->btfd < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorOpeningBktrDev, strerror(errno)); priv->videoready = FALSE; }if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "SETEORSFMT", strerror(errno)); }if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSINPUT, &priv->source) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORSINPUT", strerror(errno)); }tmp_fps = priv->fps;if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSFPS, &tmp_fps) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORSFPS", strerror(errno)); }if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORSGEQ", strerror(errno)); }if(priv->videoready == TRUE) { priv->framebufsize = (priv->geom.columns * priv->geom.rows * 2); priv->livebuf = (u_char *)mmap((caddr_t)0, priv->framebufsize, PROT_READ, MAP_SHARED, priv->btfd, (off_t)0); if(priv->livebuf == (u_char *) MAP_FAILED) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848MmapFailed, strerror(errno)); priv->videoready = FALSE; } for(count=0;count<RINGSIZE;count++) { priv->framebuf[count].buf = malloc(priv->framebufsize); if(priv->framebuf[count].buf == NULL) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848FrameBufAllocFailed, strerror(errno)); priv->videoready = FALSE; break; } priv->framebuf[count].dirty = TRUE; priv->framebuf[count].timestamp = 0; } }/* Tuner Configuration */priv->tunerready = TRUE;priv->tunerfd = open(priv->tunerdev, O_RDONLY);if(priv->tunerfd < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorOpeningTunerDev, strerror(errno)); priv->tunerready = FALSE; }/* Audio Configuration */priv->dspready = TRUE;priv->dspsamplesize = 16;priv->dspstereo = 1;priv->dspspeed = 44100;priv->dspfmt = AFMT_S16_LE;priv->dspbytesread = 0;priv->dsprate = priv->dspspeed * priv->dspsamplesize/8*(priv->dspstereo+1);priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/priv->fps * (priv->dspstereo+1);if((priv->dspfd = open (priv->dspdev, O_RDONLY, 0)) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorOpeningDspDev, strerror(errno)); priv->dspready = FALSE; } marg = (256 << 16) | 12;if (ioctl(priv->dspfd, SNDCTL_DSP_SETFRAGMENT, &marg ) < 0 ) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "SNDCTL_DSP_SETFRAGMENT", strerror(errno)); priv->dspready = FALSE; }if((priv->dspready == TRUE) && ((ioctl(priv->dspfd, SNDCTL_DSP_SAMPLESIZE, &priv->dspsamplesize) == -1) || (ioctl(priv->dspfd, SNDCTL_DSP_STEREO, &priv->dspstereo) == -1) || (ioctl(priv->dspfd, SNDCTL_DSP_SPEED, &priv->dspspeed) == -1) || (ioctl(priv->dspfd, SNDCTL_DSP_SETFMT, &priv->dspfmt) == -1))) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorConfiguringDsp, strerror(errno)); close(priv->dspfd); priv->dspready = FALSE; }return(1);}/* that's the real start, we'got the format parameters (checked with control) */static int start(priv_t *priv){int tmp;struct timeval curtime;int marg;fprintf(stderr,"START\n");if(priv->videoready == FALSE) return(0);signal(SIGUSR1, processframe);signal(SIGALRM, processframe);marg = SIGUSR1;if(ioctl(priv->btfd, METEORSSIGNAL, &marg) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORSSIGNAL", strerror(errno)); return(0); }read(priv->dspfd, &tmp, 2);gettimeofday(&curtime, NULL);priv->starttime = curtime.tv_sec + (curtime.tv_usec *.000001);marg = METEOR_CAP_CONTINOUS;if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORCAPTUR", strerror(errno)); return(0); }return(1);}static int uninit(priv_t *priv){int marg;if(priv->videoready == FALSE) return(0);marg = METEOR_SIG_MODE_MASK;if(ioctl( priv->btfd, METEORSSIGNAL, &marg) < 0 ) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "METEORSSIGNAL", strerror(errno)); return(0); }marg = METEOR_CAP_STOP_CONT;if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0 ) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848UnableToStopCapture, strerror(errno)); return(0); }close(priv->btfd);close(priv->dspfd);priv->dspfd = -1;priv->btfd = -1;priv->dspready = priv->videoready = FALSE;return(1);}static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len){sigset_t sa_mask;if(priv->videoready == FALSE) return(0);alarm(1);sigfillset(&sa_mask);sigdelset(&sa_mask,SIGINT);sigdelset(&sa_mask,SIGUSR1);sigdelset(&sa_mask,SIGALRM);sigsuspend(&sa_mask);alarm(0);memcpy(buffer, priv->livebuf, len);/* PTS = 0, show the frame NOW, this routine is only used in playback mode without audio capture .. */return(0); }static double grab_video_frame(priv_t *priv, char *buffer, int len){double timestamp=0;sigset_t sa_mask;if(priv->videoready == FALSE) return(0);if(priv->immediatemode == TRUE) { return grabimmediate_video_frame(priv, buffer, len); }while(priv->framebuf[priv->curbufframe].dirty == TRUE) { alarm(1); sigemptyset(&sa_mask); sigsuspend(&sa_mask); alarm(0); }memcpy(buffer, priv->framebuf[priv->curbufframe].buf, len);timestamp = priv->framebuf[priv->curbufframe].timestamp;priv->framebuf[priv->curbufframe].dirty = TRUE;priv->curbufframe++;if(priv->curbufframe >= RINGSIZE) priv->curbufframe = 0;return(timestamp-priv->starttime);}static int get_video_framesize(priv_t *priv){return(priv->geom.columns*priv->geom.rows*16/8);}static double grab_audio_frame(priv_t *priv, char *buffer, int len){struct timeval curtime;double curpts;double timeskew;int bytesread;int ret;if(priv->dspready == FALSE) return 0;gettimeofday(&curtime, NULL);/* Get exactly one frame of audio, which forces video sync to audio.. */bytesread=read(priv->dspfd, buffer, len); while(bytesread < len) { ret=read(priv->dspfd, &buffer[bytesread], len-bytesread); if(ret == -1) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848ErrorReadingAudio, strerror(errno)); return 0; } bytesread+=ret; }priv->dspbytesread += bytesread;curpts = curtime.tv_sec + curtime.tv_usec * .000001;timeskew = priv->dspbytesread * 1.0 / priv->dsprate - (curpts-priv->starttime);if(timeskew > .125/priv->fps) { priv->starttime -= timeskew; }else { if(timeskew < -.125/priv->fps) { priv->starttime -= timeskew; } }return(priv->dspbytesread * 1.0 / priv->dsprate);}static int get_audio_framesize(priv_t *priv){int bytesavail;#ifdef USE_SUN_AUDIOstruct audio_info auinf;#endifif(priv->dspready == FALSE) return 0;#ifdef USE_SUN_AUDIOif(ioctl(priv->dspfd, AUDIO_GETINFO, &auinf) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "AUDIO_GETINFO", strerror(errno)); return(TVI_CONTROL_FALSE); }else bytesavail = auinf.record.seek; /* *priv->dspsamplesize; */#elseif(ioctl(priv->dspfd, FIONREAD, &bytesavail) < 0) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_Bt848IoctlFailed, "FIONREAD", strerror(errno)); return(TVI_CONTROL_FALSE); }#endif/* When mencoder wants audio data, it wants data.. it won't go do anything else until it gets it :( */if(bytesavail == 0) return FRAGSIZE;return(bytesavail);}static int getinput(int innumber){switch(innumber) { case 0: return METEOR_INPUT_DEV0; /* RCA */ case 1: return METEOR_INPUT_DEV1; /* Tuner */ case 2: return METEOR_INPUT_DEV2; /* In 1 */ case 3: return METEOR_INPUT_DEV3; /* In 2 */ case 4: return METEOR_INPUT_DEV_RGB; /* RGB */ case 5: return METEOR_INPUT_DEV_SVIDEO; /* SVid */ }return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -