📄 tv.c
字号:
break; default: mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnknownImageFormat,tvh->tv_param->outfmt); } funcs->control(tvh->priv, TVI_CONTROL_VID_SET_FORMAT, &tvh->tv_param->outfmt); } /* set some params got from cmdline */ funcs->control(tvh->priv, TVI_CONTROL_SPC_SET_INPUT, &tvh->tv_param->input);#ifdef HAVE_TV_V4L2 if (!strcmp(tvh->tv_param->driver, "v4l2") && tvh->tv_param->normid >= 0) { mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_SelectedNormId, tvh->tv_param->normid); if (funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->tv_param->normid) != TVI_CONTROL_TRUE) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm); } } else {#endif /* select video norm */ tvh->norm = norm_from_string(tvh, tvh->tv_param->norm); mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_SelectedNorm, tvh->tv_param->norm); if (funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->norm) != TVI_CONTROL_TRUE) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm); }#ifdef HAVE_TV_V4L2 }#endif#ifdef HAVE_TV_V4L1 if ( tvh->tv_param->mjpeg ) { /* set width to expected value */ if (tvh->tv_param->width == -1) { tvh->tv_param->width = 704/tvh->tv_param->decimation; } if (tvh->tv_param->height == -1) { if ( tvh->norm != TV_NORM_NTSC ) tvh->tv_param->height = 576/tvh->tv_param->decimation; else tvh->tv_param->height = 480/tvh->tv_param->decimation; } mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TV_MJP_WidthHeight, tvh->tv_param->width, tvh->tv_param->height); }#endif /* limits on w&h are norm-dependent -- JM */ /* set width */ if (tvh->tv_param->width != -1) { if (funcs->control(tvh->priv, TVI_CONTROL_VID_CHK_WIDTH, &tvh->tv_param->width) == TVI_CONTROL_TRUE) funcs->control(tvh->priv, TVI_CONTROL_VID_SET_WIDTH, &tvh->tv_param->width); else { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnableToSetWidth, tvh->tv_param->width); funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &tvh->tv_param->width); } } /* set height */ if (tvh->tv_param->height != -1) { if (funcs->control(tvh->priv, TVI_CONTROL_VID_CHK_HEIGHT, &tvh->tv_param->height) == TVI_CONTROL_TRUE) funcs->control(tvh->priv, TVI_CONTROL_VID_SET_HEIGHT, &tvh->tv_param->height); else { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnableToSetHeight, tvh->tv_param->height); funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &tvh->tv_param->height); } } if (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) != TVI_CONTROL_TRUE) { mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TV_NoTuner); goto done; } /* select channel list */ for (i = 0; chanlists[i].name != NULL; i++) { if (!strcasecmp(chanlists[i].name, tvh->tv_param->chanlist)) { tvh->chanlist = i; tvh->chanlist_s = chanlists[i].list; break; } } if (tvh->chanlist == -1) mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TV_UnableFindChanlist, tvh->tv_param->chanlist); else mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_SelectedChanlist, chanlists[tvh->chanlist].name, chanlists[tvh->chanlist].count); if (tvh->tv_param->freq && tvh->tv_param->channel) { mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TV_ChannelFreqParamConflict); goto done; } /* Handle channel names */ if (tvh->tv_param->channels) { parse_channels(tvh); } else tv_channel_last_real = malloc(5); if (tv_channel_list) { int i; int channel = 0; if (tvh->tv_param->channel) { if (isdigit(*tvh->tv_param->channel)) /* if tvh->tv_param->channel begins with a digit interpret it as a number */ channel = atoi(tvh->tv_param->channel); else { /* if tvh->tv_param->channel does not begin with a digit set the first channel that contains tvh->tv_param->channel in its name */ tv_channel_current = tv_channel_list; while ( tv_channel_current ) { if ( strstr(tv_channel_current->name, tvh->tv_param->channel) ) break; tv_channel_current = tv_channel_current->next; } if ( !tv_channel_current ) tv_channel_current = tv_channel_list; } } else channel = 1; if ( channel ) { tv_channel_current = tv_channel_list; for (i = 1; i < channel; i++) if (tv_channel_current->next) tv_channel_current = tv_channel_current->next; } mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TV_SelectedChannel3, tv_channel_current->number, tv_channel_current->name, (float)tv_channel_current->freq/1000); tv_set_freq(tvh, (unsigned long)(((float)tv_channel_current->freq/1000)*16)); tv_channel_last = tv_channel_current; } else { /* we need to set frequency */ if (tvh->tv_param->freq) { unsigned long freq = atof(tvh->tv_param->freq)*16; /* set freq in MHz */ funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &freq); funcs->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &freq); mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_SelectedFrequency, freq, (float)freq/16); } if (tvh->tv_param->channel) { struct CHANLIST cl; mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_RequestedChannel, tvh->tv_param->channel); for (i = 0; i < chanlists[tvh->chanlist].count; i++) { cl = tvh->chanlist_s[i]; // printf("count%d: name: %s, freq: %d\n", // i, cl.name, cl.freq); if (!strcasecmp(cl.name, tvh->tv_param->channel)) { strcpy(tv_channel_last_real, cl.name); tvh->channel = i; mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TV_SelectedChannel2, cl.name, (float)cl.freq/1000); tv_set_freq(tvh, (unsigned long)(((float)cl.freq/1000)*16)); break; } } } } /* grep frequency in chanlist */ { unsigned long i2; int freq; tv_get_freq(tvh, &i2); freq = (int) (((float)(i2/16))*1000)+250; for (i = 0; i < chanlists[tvh->chanlist].count; i++) { if (tvh->chanlist_s[i].freq == freq) { tvh->channel = i+1; break; } } }done: /* also start device! */ return 1;}static tvi_handle_t *tv_begin(tv_param_t* tv_param){ int i; tvi_handle_t* h; if(tv_param->driver && !strcmp(tv_param->driver,"help")){ mp_msg(MSGT_TV,MSGL_INFO,MSGTR_TV_AvailableDrivers); for(i=0;tvi_driver_list[i];i++){ mp_msg(MSGT_TV,MSGL_INFO," %s\t%s",tvi_driver_list[i]->short_name,tvi_driver_list[i]->name); if(tvi_driver_list[i]->comment) mp_msg(MSGT_TV,MSGL_INFO," (%s)",tvi_driver_list[i]->comment); mp_msg(MSGT_TV,MSGL_INFO,"\n"); } return NULL; } for(i=0;tvi_driver_list[i];i++){ if (!tv_param->driver || !strcmp(tvi_driver_list[i]->short_name, tv_param->driver)){ h=tvi_driver_list[i]->tvi_init(tv_param); //Requested driver initialization failed if (!h && tv_param->driver) return NULL; //Driver initialization failed during autodetection process. if (!h) continue; h->tv_param=tv_param; mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TV_DriverInfo, tvi_driver_list[i]->short_name, tvi_driver_list[i]->name, tvi_driver_list[i]->author, tvi_driver_list[i]->comment?tvi_driver_list[i]->comment:""); tv_param->driver=strdup(tvi_driver_list[i]->short_name); return h; } } if(tv_param->driver) mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_NoSuchDriver, tv_param->driver); else mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_DriverAutoDetectionFailed); return(NULL);}static int tv_uninit(tvi_handle_t *tvh){ int res; if(!tvh) return 1; if (!tvh->priv) return 1; res=tvh->functions->uninit(tvh->priv); if(res) tvh->priv=NULL; return res;}static demuxer_t* demux_open_tv(demuxer_t *demuxer){ tvi_handle_t *tvh; sh_video_t *sh_video; sh_audio_t *sh_audio = NULL; tvi_functions_t *funcs; demuxer->priv=NULL; if(!(tvh=tv_begin(demuxer->stream->priv))) return NULL; if (!tvh->functions->init(tvh->priv)) return NULL; tvh->functions->control(tvh->priv,TVI_CONTROL_VBI_INIT,&(tvh->tv_param->tdevice)); if (!open_tv(tvh)){ tv_uninit(tvh); return NULL; } funcs = tvh->functions; demuxer->priv=tvh; sh_video = new_sh_video(demuxer, 0); /* get IMAGE FORMAT */ funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format);// if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format))// sh_video->format = 0x0; /* set FPS and FRAMETIME */ if(!sh_video->fps) { float tmp; if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &tmp) != TVI_CONTROL_TRUE) sh_video->fps = 25.0f; /* on PAL */ else sh_video->fps = tmp; } if (tvh->tv_param->fps != -1.0f) sh_video->fps = tvh->tv_param->fps; sh_video->frametime = 1.0f/sh_video->fps; /* If playback only mode, go to immediate mode, fail silently */ if(tvh->tv_param->immediate == 1) { funcs->control(tvh->priv, TVI_CONTROL_IMMEDIATE, 0); tvh->tv_param->noaudio = 1; } /* disable TV audio if -nosound is present */ if (!demuxer->audio || demuxer->audio->id == -2) { tvh->tv_param->noaudio = 1; } /* set width */ funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); /* set height */ funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h); demuxer->video->sh = sh_video; sh_video->ds = demuxer->video; demuxer->video->id = 0; demuxer->seekable = 0; /* here comes audio init */ if (tvh->tv_param->noaudio == 0 && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) { int audio_format; int sh_audio_format; char buf[128]; /* yeah, audio is present */ funcs->control(tvh->priv, TVI_CONTROL_AUD_SET_SAMPLERATE, &tvh->tv_param->audiorate); if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE) goto no_audio; switch(audio_format) { case AF_FORMAT_U8: case AF_FORMAT_S8: case AF_FORMAT_U16_LE: case AF_FORMAT_U16_BE: case AF_FORMAT_S16_LE: case AF_FORMAT_S16_BE: case AF_FORMAT_S32_LE: case AF_FORMAT_S32_BE: sh_audio_format = 0x1; /* PCM */ break; case AF_FORMAT_IMA_ADPCM: case AF_FORMAT_MU_LAW: case AF_FORMAT_A_LAW:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -