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

📄 ffmpeg.c

📁 video motion detection of linux base
💻 C
📖 第 1 页 / 共 2 页
字号:
	ffmpeg->video_outbuf = NULL;	if (!(ffmpeg->oc->oformat->flags & AVFMT_RAWPICTURE)) {		/* allocate output buffer */		/* XXX: API change will be done */		ffmpeg->video_outbuf_size = 200000;		ffmpeg->video_outbuf = mymalloc(ffmpeg->video_outbuf_size);	}	/* allocate the encoded raw picture */	ffmpeg->picture = avcodec_alloc_frame();	if (!ffmpeg->picture) {		motion_log(LOG_ERR, 1, "avcodec_alloc_frame - could not alloc frame");		ffmpeg_cleanups(ffmpeg);		return (NULL);	}	/* set variable bitrate if requested */	if (ffmpeg->vbr) {		ffmpeg->picture->quality = ffmpeg->vbr;	}	/* set the frame data */	ffmpeg->picture->data[0] = y;	ffmpeg->picture->data[1] = u;	ffmpeg->picture->data[2] = v;	ffmpeg->picture->linesize[0] = ffmpeg->c->width;	ffmpeg->picture->linesize[1] = ffmpeg->c->width / 2;	ffmpeg->picture->linesize[2] = ffmpeg->c->width / 2;	/* open the output file, if needed */	if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {		char file_proto[256];		/* Use append file protocol for mpeg1, to get the append behavior from 		 * url_fopen, but no protocol (=> default) for other codecs.		 */		if(is_mpeg1) {			snprintf(file_proto, sizeof(file_proto), APPEND_PROTO ":%s", filename);		} else {			snprintf(file_proto, sizeof(file_proto), "%s", filename);		}		if (url_fopen(&ffmpeg->oc->pb, file_proto, URL_WRONLY) < 0) {			/* path did not exist? */			if (errno == ENOENT) {				/* create path for file (don't use file_proto)... */				if (create_path(filename) == -1) {					ffmpeg_cleanups(ffmpeg);					return (NULL);				}				/* and retry opening the file (use file_proto) */				if (url_fopen(&ffmpeg->oc->pb, file_proto, URL_WRONLY) < 0) {					motion_log(LOG_ERR, 1, "url_fopen - error opening file %s",filename);					ffmpeg_cleanups(ffmpeg);					return (NULL);				}				/* Permission denied */			} else if (errno ==  EACCES) {				motion_log(LOG_ERR, 1,				           "url_fopen - error opening file %s"				           " ... check access rights to target directory", filename);				/* create path for file... */				ffmpeg_cleanups(ffmpeg);				return (NULL);			} else {				motion_log(LOG_ERR, 1, "Error opening file %s", filename);				ffmpeg_cleanups(ffmpeg);				return (NULL);			}		}	}	/* write the stream header, if any */	av_write_header(ffmpeg->oc);		return ffmpeg;}/*  Clean up ffmpeg struct if something was wrong*/void ffmpeg_cleanups(struct ffmpeg *ffmpeg){	int i;	/* close each codec */	if (ffmpeg->video_st) {		pthread_mutex_lock(&global_lock);		avcodec_close(AVSTREAM_CODEC_PTR(ffmpeg->video_st));		pthread_mutex_unlock(&global_lock);			av_freep(&ffmpeg->picture);		av_freep(&ffmpeg->video_outbuf);	}	/* free the streams */	for (i = 0; i < ffmpeg->oc->nb_streams; i++) {		av_freep(&ffmpeg->oc->streams[i]);	}/*		if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {			// close the output file 			if (ffmpeg->oc->pb) url_fclose(&ffmpeg->oc->pb);		}*/	/* free the stream */	av_free(ffmpeg->oc);#if LIBAVFORMAT_BUILD >= 4629	free(ffmpeg->c);#endif	free(ffmpeg);}/* Closes a video file. */void ffmpeg_close(struct ffmpeg *ffmpeg){	int i;	/* close each codec */	if (ffmpeg->video_st) {		pthread_mutex_lock(&global_lock);		avcodec_close(AVSTREAM_CODEC_PTR(ffmpeg->video_st));		pthread_mutex_unlock(&global_lock);		av_freep(&ffmpeg->picture);		av_freep(&ffmpeg->video_outbuf);	}	/* write the trailer, if any */	av_write_trailer(ffmpeg->oc);	/* free the streams */	for (i = 0; i < ffmpeg->oc->nb_streams; i++) {		av_freep(&ffmpeg->oc->streams[i]);	}	if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {		/* close the output file */		url_fclose(&ffmpeg->oc->pb);	}	/* free the stream */	av_free(ffmpeg->oc);#if LIBAVFORMAT_BUILD >= 4629	free(ffmpeg->c);#endif	free(ffmpeg);}/* Puts the image pointed to by ffmpeg->picture. */void ffmpeg_put_image(struct ffmpeg *ffmpeg) {	ffmpeg_put_frame(ffmpeg, ffmpeg->picture);}/* Puts an arbitrary picture defined by y, u and v. */void ffmpeg_put_other_image(struct ffmpeg *ffmpeg, unsigned char *y,                            unsigned char *u, unsigned char *v){	AVFrame *picture;	/* allocate the encoded raw picture */	picture = ffmpeg_prepare_frame(ffmpeg, y, u, v);	if (picture) {		ffmpeg_put_frame(ffmpeg, picture);		free(picture);	}}/* Encodes and writes a video frame using the av_write_frame API. This is * a helper function for ffmpeg_put_image and ffmpeg_put_other_image.  */void ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){	int out_size, ret;#ifdef FFMPEG_AVWRITEFRAME_NEWAPI	AVPacket pkt;	av_init_packet(&pkt); /* init static structure */	pkt.stream_index = ffmpeg->video_st->index;#endif /* FFMPEG_AVWRITEFRAME_NEWAPI */	if (ffmpeg->oc->oformat->flags & AVFMT_RAWPICTURE) {		/* raw video case. The API will change slightly in the near future for that */#ifdef FFMPEG_AVWRITEFRAME_NEWAPI		pkt.flags |= PKT_FLAG_KEY;		pkt.data = (uint8_t *)pic;		pkt.size = sizeof(AVPicture);		ret = av_write_frame(ffmpeg->oc, &pkt);#else		ret = av_write_frame(ffmpeg->oc, ffmpeg->video_st->index,			(uint8_t *)pic, sizeof(AVPicture));#endif /* FFMPEG_AVWRITEFRAME_NEWAPI */	} else {		/* encode the image */		out_size = avcodec_encode_video(AVSTREAM_CODEC_PTR(ffmpeg->video_st),		                                ffmpeg->video_outbuf, 		                                ffmpeg->video_outbuf_size, pic);		/* if zero size, it means the image was buffered */		if (out_size != 0) {			/* write the compressed frame in the media file */			/* XXX: in case of B frames, the pts is not yet valid */#ifdef FFMPEG_AVWRITEFRAME_NEWAPI			pkt.pts = AVSTREAM_CODEC_PTR(ffmpeg->video_st)->coded_frame->pts;			if (AVSTREAM_CODEC_PTR(ffmpeg->video_st)->coded_frame->key_frame) {				pkt.flags |= PKT_FLAG_KEY;			}			pkt.data = ffmpeg->video_outbuf;			pkt.size = out_size;			ret = av_write_frame(ffmpeg->oc, &pkt);#else			ret = av_write_frame(ffmpeg->oc, ffmpeg->video_st->index, 			                     ffmpeg->video_outbuf, out_size);#endif /* FFMPEG_AVWRITEFRAME_NEWAPI */		} else {			ret = 0;		}	}		if (ret != 0) {		motion_log(LOG_ERR, 1, "Error while writing video frame");		return;	}}/* Allocates and prepares a picture frame by setting up the U, Y and V pointers in * the frame according to the passed pointers. * * Returns NULL If the allocation fails. * * The returned AVFrame pointer must be freed after use. */AVFrame *ffmpeg_prepare_frame(struct ffmpeg *ffmpeg, unsigned char *y,                              unsigned char *u, unsigned char *v){	AVFrame *picture;	picture = avcodec_alloc_frame();	if (!picture) {		motion_log(LOG_ERR, 1, "Could not alloc frame");		return NULL;	}	/* take care of variable bitrate setting */	if (ffmpeg->vbr) {		picture->quality = ffmpeg->vbr;	}		/* setup pointers and line widths */	picture->data[0] = y;	picture->data[1] = u;	picture->data[2] = v;	picture->linesize[0] = ffmpeg->c->width;	picture->linesize[1] = ffmpeg->c->width / 2;	picture->linesize[2] = ffmpeg->c->width / 2;	return picture;}/** ffmpeg_deinterlace *      Make the image suitable for deinterlacing using ffmpeg, then deinterlace the picture. *  * Parameters *      img     image in YUV420P format *      width   image width in pixels *      height  image height in pixels * * Returns *      Function returns nothing. *      img     contains deinterlaced image */void ffmpeg_deinterlace(unsigned char *img, int width, int height){	AVFrame *picture;	int width2 = width / 2;		picture = avcodec_alloc_frame();	if (!picture) {		motion_log(LOG_ERR, 1, "Could not alloc frame");		return;	}		picture->data[0] = img;	picture->data[1] = img+width*height;	picture->data[2] = picture->data[1]+(width*height)/4;	picture->linesize[0] = width;	picture->linesize[1] = width2;	picture->linesize[2] = width2;		/* We assume using 'PIX_FMT_YUV420P' always */	avpicture_deinterlace((AVPicture *)picture, (AVPicture *)picture, PIX_FMT_YUV420P, width, height);		av_free(picture);		return;}/** ffmpeg_avcodec_log *      Handle any logging output from the ffmpeg library avcodec. *  * Parameters *      *ignoreme  A pointer we will ignore *      errno_flag The error number value *      fmt        Text message to be used for log entry in printf() format. *      ap         List of variables to be used in formatted message text. * * Returns *      Function returns nothing. */void ffmpeg_avcodec_log(void *ignoreme ATTRIBUTE_UNUSED, int errno_flag, const char *fmt, ...){	char buf[1024];	va_list ap;	/* Do not log the message coming from avcodec if the debug_level is not set. */	if (debug_level) {		/* Get the message from the argument list passed in */		va_start(ap, fmt);		/* Flatten the message coming in from avcodec */		vsnprintf(buf, sizeof(buf), fmt, ap);		/* If the debug_level is correct then send the message to the motion logging routine. */		motion_log(LOG_ERR, 0, "ffmpeg_avcodec_log: %s - flag %d", buf, errno_flag);		/* Clean up the argument list routine */		va_end(ap);	}}#endif /* HAVE_FFMPEG */

⌨️ 快捷键说明

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