⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tvi_v4l2.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 4 页
字号:
	set_mute(priv, 1);    }    /* free memory and close device */    free(priv->map);		priv->map = NULL;    priv->mapcount = 0;    close(priv->video_fd);	priv->video_fd  = -1;    free(priv->video_dev);	priv->video_dev = NULL;    if (priv->video_ringbuffer) {	int i;	for (i = 0; i < priv->video_buffer_size_current; i++) {	    free(priv->video_ringbuffer[i]);	}	free(priv->video_ringbuffer);    }    if (priv->video_timebuffer)	free(priv->video_timebuffer);    if (!tv_param_noaudio) {	if (priv->audio_ringbuffer)	    free(priv->audio_ringbuffer);	if (priv->audio_skew_buffer)	    free(priv->audio_skew_buffer);	if (priv->audio_skew_delta_buffer)	    free(priv->audio_skew_delta_buffer);    }    /* show some nice statistics ;-) */    mp_msg(MSGT_TV, MSGL_INFO,	   "%s: %d frames successfully processed, %d frames dropped.\n",	   info.short_name, priv->frames, dropped);    mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",	   info.short_name, priv->video_buffer_size_current);    return 1;}/* initialisation */static int init(priv_t *priv){    int i;    if (tv_param_immediate == 1)	tv_param_noaudio = 1;    priv->audio_ringbuffer = NULL;    priv->audio_skew_buffer = NULL;    priv->audio_skew_delta_buffer = NULL;    /* Open the video device. */    priv->video_fd = open(priv->video_dev, O_RDWR);    if (priv->video_fd < 0) {	mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",	       info.short_name, priv->video_dev, strerror(errno));	uninit(priv);	return 0;    }    mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",	   info.short_name, priv->video_dev, priv->video_fd);    /*    ** Query the video capabilities and current settings    ** for further control calls.    */    if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {	mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",	       info.short_name, strerror(errno));	uninit(priv);	return 0;    }    if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))    {	mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",	       priv->video_dev);	return 0;    }    if (getfmt(priv) < 0 || getstd(priv) < 0) {	uninit(priv);	return 0;    }    /*    ** if this device has got a tuner query it's settings    ** otherwise set some nice defaults    */    if (priv->capability.capabilities & V4L2_CAP_TUNER) {	if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {	    mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",		   info.short_name, strerror(errno));	    uninit(priv);	    return 0;	}    }    mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);    if (priv->capability.capabilities & V4L2_CAP_TUNER) {	mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",		(priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",		(priv->tuner.capability & V4L2_TUNER_CAP_LANG1)  ? " LANG1"  : "",		(priv->tuner.capability & V4L2_TUNER_CAP_LANG2)  ? " LANG2"  : "");	mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",		(priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO)   ? " MONO"   : "",		(priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",		(priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1)  ? " LANG1"  : "",		(priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2)  ? " LANG2"  : "");    }    mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",	   priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?	   "  video capture": "",	   priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?	   "  video output": "",	   priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?	   "  video overlay": "",	   priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?	   "  VBI capture device": "",	   priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?	   "  VBI output": "",	   priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?	   "  RDS data capture": "",	   priv->capability.capabilities & V4L2_CAP_TUNER?	   "  tuner": "",	   priv->capability.capabilities & V4L2_CAP_AUDIO?	   "  audio": "",	   priv->capability.capabilities & V4L2_CAP_READWRITE?	   "  read/write": "",	   priv->capability.capabilities & V4L2_CAP_ASYNCIO?	   "  async i/o": "",	   priv->capability.capabilities & V4L2_CAP_STREAMING?	   "  streaming": "");    mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");    for (i = 0;; i++) {	struct v4l2_standard standard;	memset(&standard, 0, sizeof(standard));	standard.index = i;	if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))	    break;	printf(" %d = %s;", i, standard.name);    }    mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");    for (i = 0; 1; i++) {	struct v4l2_input input;	input.index = i;	if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {	    break;	}	mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);    }    if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {	mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",	       info.short_name, strerror(errno));    }    mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);    for (i = 0; ; i++) {	struct v4l2_fmtdesc fmtdesc;	fmtdesc.index = i;	fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;	if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {	    break;	}	mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",	       pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),	       fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));    }    mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",	   pixfmt2name(priv->format.fmt.pix.pixelformat));    /* set some nice defaults */    if (getfmt(priv) < 0) return 0;    priv->format.fmt.pix.width  = 640;    priv->format.fmt.pix.height = 480;    if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {	mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",	       info.short_name, strerror(errno));	uninit(priv);	return 0;    }//    if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !tv_param_force_audio) tv_param_noaudio = 1;    if (priv->capability.capabilities & V4L2_CAP_TUNER) {	struct v4l2_control control;	if (tv_param_amode >= 0) {	    mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);	    priv->tuner.audmode = amode2v4l(tv_param_amode);	    if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {		mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",		       info.short_name, strerror(errno));		return TVI_CONTROL_FALSE;	    }	}	mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,		(priv->tuner.audmode == V4L2_TUNER_MODE_MONO)   ? " MONO"   : "",		(priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",		(priv->tuner.audmode == V4L2_TUNER_MODE_LANG1)  ? " LANG1"  : "",		(priv->tuner.audmode == V4L2_TUNER_MODE_LANG2)  ? " LANG2"  : "");	if (tv_param_volume >= 0) {	    control.id = V4L2_CID_AUDIO_VOLUME;	    control.value = tv_param_volume;	    set_control(priv, &control, 0);	}	if (tv_param_bass >= 0) {	    control.id = V4L2_CID_AUDIO_BASS;	    control.value = tv_param_bass;	    set_control(priv, &control, 0);	}	if (tv_param_treble >= 0) {	    control.id = V4L2_CID_AUDIO_TREBLE;	    control.value = tv_param_treble;	    set_control(priv, &control, 0);	}	if (tv_param_balance >= 0) {	    control.id = V4L2_CID_AUDIO_BALANCE;	    control.value = tv_param_balance;	    set_control(priv, &control, 0);	}    }        /* audio init */    if (!tv_param_noaudio) {#if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)	if (tv_param_alsa)	    audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);	else	    audio_in_init(&priv->audio_in, AUDIO_IN_OSS);#else	audio_in_init(&priv->audio_in, AUDIO_IN_OSS);#endif	if (priv->audio_dev) {	    audio_in_set_device(&priv->audio_in, priv->audio_dev);	}	audio_in_set_samplerate(&priv->audio_in, 44100);	if (priv->capability.capabilities & V4L2_CAP_TUNER) {	    if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {		audio_in_set_channels(&priv->audio_in, 2);	    } else {		audio_in_set_channels(&priv->audio_in, 1);	    }	} else {	    if (tv_param_forcechan >= 0) {		audio_in_set_channels(&priv->audio_in, tv_param_forcechan);	    } else {		audio_in_set_channels(&priv->audio_in, 2);	    }	}	if (audio_in_setup(&priv->audio_in) < 0) return 0;//	setup_audio_buffer_sizes(priv);    }    return 1;}static int get_capture_buffer_size(priv_t *priv){    int bufsize, cnt;    int w = priv->format.fmt.pix.width;    int h = priv->format.fmt.pix.height;    int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);    int bytesperline = w*d/8;    if (tv_param_buffer_size >= 0) {	bufsize = tv_param_buffer_size*1024*1024;    } else {#ifdef HAVE_SYS_SYSINFO_H	struct sysinfo si;		sysinfo(&si);	if (si.totalram<2*1024*1024) {	    bufsize = 1024*1024;	} else {	    bufsize = si.totalram/2;	}#else	bufsize = 16*1024*1024;#endif    }        cnt = bufsize/(h*bytesperline);    if (cnt < 2) cnt = 2;        return cnt;}/* that's the real start, we'got the format parameters (checked with control) */static int start(priv_t *priv){    struct v4l2_requestbuffers request;    int i;    /* setup audio parameters */    /* we need this to size the audio buffer properly */    if (priv->immediate_mode) {	priv->video_buffer_size_max = 2;    } else {	priv->video_buffer_size_max = get_capture_buffer_size(priv);    }        if (!tv_param_noaudio) {	setup_audio_buffer_sizes(priv);	priv->audio_skew_buffer = (long long*)malloc(sizeof(long long)*priv->aud_skew_cnt);	if (!priv->audio_skew_buffer) {	    mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));	    return 0;	}	priv->audio_skew_delta_buffer = (long long*)malloc(sizeof(long long)*priv->aud_skew_cnt);	if (!priv->audio_skew_delta_buffer) {	    mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));	    return 0;	}	priv->audio_ringbuffer = (unsigned char*)malloc(priv->audio_in.blocksize*priv->audio_buffer_size);	if (!priv->audio_ringbuffer) {	    mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));	    return 0;	}	priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate								    *priv->audio_in.channels								    *priv->audio_in.bytes_per_sample);	priv->audio_head = 0;	priv->audio_tail = 0;	priv->audio_cnt = 0;	priv->audio_drop = 0;	priv->audio_skew = 0;	priv->audio_skew_total = 0;	priv->audio_skew_delta_total = 0;	priv->audio_recv_blocks_total = 0;	priv->audio_sent_blocks_total = 0;    }    /* setup video parameters */    if (!tv_param_noaudio) {	if (priv->video_buffer_size_max < 3.0*(priv->standard.frameperiod.denominator /					       priv->standard.frameperiod.numerator)	    *priv->audio_secs_per_block) {	    mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"		   "You will probably experience heavy framedrops.\n");	}    }        {	int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;		mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",	       priv->video_buffer_size_max,	       priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));    }    priv->video_ringbuffer = (unsigned char**)malloc(priv->video_buffer_size_max*sizeof(unsigned char*));    if (!priv->video_ringbuffer) {	mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));	return 0;    }    for (i = 0; i < priv->video_buffer_size_max; i++)	priv->video_ringbuffer[i] = NULL;    priv->video_timebuffer = (long long*)malloc(sizeof(long long) * priv->video_buffer_size_max);    if (!priv->video_timebuffer) {	mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));	return 0;    }    priv->video_head = 0;    priv->video_tail = 0;    priv->video_cnt = 0;        /* request buffers */    if (priv->immediate_mode) {	request.count = 2;    } else {	request.count = BUFFER_COUNT;    }        request.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;    request.memory = V4L2_MEMORY_MMAP;    if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {	mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",	       info.short_name, strerror(errno));	return 0;    }    /* query buffers */    if (!(priv->map = malloc(sizeof(struct map) * request.count))) {	mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",	       info.short_name, strerror(errno));	return 0;    }    /* map and queue buffers */    for (i = 0; i < request.count; i++) {	memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));	priv->map[i].buf.index = i;	priv->map[i].buf.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;	priv->map[i].buf.memory  = V4L2_MEMORY_MMAP;	if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {	    mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",		   info.short_name, strerror(errno));	    free(priv->map);	    priv->map = NULL;	    return 0;	}	priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |				  PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);	if (priv->map[i].addr == MAP_FAILED) {	    mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",		   info.short_name, strerror(errno));	    priv->map[i].len = 0;	    return 0;	}	priv->map[i].len = priv->map[i].buf.length;	/* count up to make sure this is correct everytime */	priv->mapcount++;	if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {	    mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",		   info.short_name, strerror(errno));	    return 0;	}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -