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

📄 cimgffmpeg.h

📁 pHash is an implementation of various perceptual hashing algorithms. A perceptual hash is a fingerpr
💻 H
📖 第 1 页 / 共 2 页
字号:
	     {		    videoStream=i;		    break;             }	     if(videoStream==-1)		   return -1; // Didn't find a video stream	}		        nb_frames = pFormatCtx->streams[videoStream]->nb_frames;	if (nb_frames > 0)	{   //the easy way if value is already contained in struct 	    av_close_input_file(pFormatCtx);	    return nb_frames;	}	else { // frames must be counted	        AVPacket packet;				//read each frame - one frame per packet		while(av_read_frame(pFormatCtx, &packet)>=0) 		{		  if(packet.stream_index==videoStream) {                  //packet is from video stream		      nb_frames++;		  }		  av_free_packet(&packet);		}		// Close the video file		av_close_input_file(pFormatCtx); 		return nb_frames;	}}float fps(const char *filename){	AVFormatContext *pFormatCtx;		// Open video file	if (av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL))	  return -1 ; // Couldn't open file				 	// Retrieve stream information	if(av_find_stream_info(pFormatCtx)<0)	  return -1; // Couldn't find stream information				// Find the first video stream	int videoStream=-1;	for(unsigned int i=0; i<pFormatCtx->nb_streams; i++)	{		     if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) 		     {			    videoStream=i;			    break;			  }		     if(videoStream==-1)			   return -1; // Didn't find a video stream	}	av_close_input_file(pFormatCtx);				int num = (pFormatCtx->streams[videoStream]->r_frame_rate).num;	int den = (pFormatCtx->streams[videoStream]->r_frame_rate).den;			return (num/den);}//! play a list of CImg's given a CImgList.     /* *  This function is not really meant to function as a video player as much as a simple  *  debugging tool.  It is meant to be run in a thread. The video is played at 1 CImg per second *  @param pVideo - a pointer to a CImgList object containing the CImg's to be played */void *PlayVideo(void *info){	video_info_t *pvideo_info = (video_info_t *)info;	int fps = pvideo_info->fps;	CImgList<unsigned char> *videolist = (CImgList<unsigned char> *)pvideo_info->pList;	CImg<> current = videolist->front();    	CImgDisplay disp(current,"video");		//display frame every second	clock_t interval = (time_t)((1/fps)*(CLOCKS_PER_SEC)); 			 	clock_t n = clock();	while (!videolist->is_empty() && !disp.is_closed)	{		if (videolist->size > 1)		{			videolist->pop_front();			current = videolist->front();			disp.display(current);			while ( n + interval > clock()){};			n = clock();		}		else if (videolist->size == 1){			videolist->pop_front();		}		else			pthread_exit(NULL);	}	pthread_exit(NULL);}/** * !write a sequence of CImg's to video file. * Purpose: write sequence of images  in cimg list at a given framerate  * using given filename, use pixel format PIX_FMT_YUV420P * The function expects the images to be either gray scale (dim v = 1) or  * rgb images (dim v == 3).  Other sizes return -1. *  * @param pImlist reference to CImgList * @param filename name of video file to create - with proper extension - e.g.  *                                ".avi, .mpeg, .wmv, etc." * @param fps int value for number of frames per second * @param stream_duration maximum length of video stream (secs) * @return int number of frames recorded to file, < 0 for errors **/template<class T>int WriteFrames(CImgList<T> *pImList,const char *filename, int fps,float stream_duration=100.0){    int width  = (pImList->front()).dimx();    int height = (pImList->front()).dimy();    int nb_channels = (pImList->front()).dimv();    if ((nb_channels != 1) && (nb_channels != 3))	throw new CImgIOException("dimv of image not acceptable");    if (!filename)        throw new CImgIOException("no file name given");    int frame_count = 0;    PixelFormat dest_pxl_fmt = PIX_FMT_YUV420P;    PixelFormat src_pxl_fmt  = (nb_channels == 3) ? PIX_FMT_RGB24 : PIX_FMT_GRAY8;        int sws_flags = SWS_FAST_BILINEAR;//interpolation method (keeping same size images for now)    AVOutputFormat *fmt = NULL;    fmt = guess_format(NULL,filename,NULL);    if (!fmt){	//default format "mpeg"         fmt = guess_format("mpeg",NULL,NULL);    }    if (!fmt){	//unable to retrieve output format        throw new CImgIOException("could not determine format from filename");    }    AVFormatContext *oc = NULL;    oc = av_alloc_format_context();     if (!oc){	//unable to allocate format context        throw new CImgIOException("mem allocation error for format context");    }    AVCodec *codec = NULL;    AVFrame *picture = NULL;    AVFrame *tmp_pict = NULL;    oc->oformat = fmt;    snprintf(oc->filename, sizeof(oc->filename),"%s",filename);    av_register_all();    //add video stream    int stream_index = 0;    AVStream *video_str = NULL;    if (fmt->video_codec != CODEC_ID_NONE) {	video_str = av_new_stream(oc,stream_index);	if (!video_str){	    //no stream allocated            av_free(oc);	    throw new CImgIOException("unable to create new video stream");	}    } else {        //no codec identified        av_free(oc);	throw new CImgIOException("no codec identified");     }    AVCodecContext *c = video_str->codec;    c->codec_id = fmt->video_codec;    c->codec_type = CODEC_TYPE_VIDEO;    c->bit_rate = 400000;    c->width = width;    c->height = height;    c->time_base.num = 1;    c->time_base.den = fps;    c->gop_size = 12;    c->pix_fmt = dest_pxl_fmt;    if (c->codec_id == CODEC_ID_MPEG2VIDEO)	c->max_b_frames = 2;    if (c->codec_id == CODEC_ID_MPEG1VIDEO)        c->mb_decision = 2;     if (av_set_parameters(oc,NULL) < 0){        //parameters not properly set        av_free(oc);        throw new CImgIOException("parameters for avcodec not properly set");    }       //dump_format(oc,0,filename,1);    //open codecs and alloc buffers    codec = avcodec_find_encoder(c->codec_id);    if (!codec){	//unable to find codec        av_free(oc);        throw new CImgIOException("no codec found");    }    if (avcodec_open(c,codec) < 0)        //fail to open codec	throw new CImgIOException("unable to open codec");    tmp_pict = avcodec_alloc_frame();    if (!tmp_pict){	//unable to allocate memory for tmp_pict frame        avcodec_close(video_str->codec);        av_free(oc);        throw new CImgIOException("mem alloc error for tmp_pict data buffer");    }    tmp_pict->linesize[0] = (src_pxl_fmt == PIX_FMT_RGB24) ? 3*width : width ;    tmp_pict->type = FF_BUFFER_TYPE_USER;    int	tmp_size = avpicture_get_size(src_pxl_fmt,width,height);    uint8_t *tmp_buffer = (uint8_t*)av_malloc(tmp_size);    if (!tmp_buffer){	//unable to allocate memory for tmp buffer        av_free(tmp_pict);        avcodec_close(video_str->codec);        av_free(oc);        throw new CImgIOException("mem alloc error for tmp buffer");    }    //associate buffer with tmp_pict    avpicture_fill((AVPicture*)tmp_pict,tmp_buffer,src_pxl_fmt,width,height);    picture = avcodec_alloc_frame();    if (!picture){	//unable to allocate picture frame        av_free(tmp_pict->data[0]);        av_free(tmp_pict);        avcodec_close(video_str->codec);        av_free(oc);        throw new CImgIOException("mem alloc error for picture frame");    }    int size = avpicture_get_size(c->pix_fmt,width,height);    uint8_t *buffer = (uint8_t*)av_malloc(size);    if (!buffer){	//unable to allocate buffer        av_free(picture);        av_free(tmp_pict->data[0]);        av_free(tmp_pict);        avcodec_close(video_str->codec);        av_free(oc);        throw new CImgIOException("mem alloc error for picture frame buffer");    }    //associate the buffer with picture    avpicture_fill((AVPicture*)picture,buffer,c->pix_fmt,width,height);    //open file    if ( !(fmt->flags & AVFMT_NOFILE) ){	if (url_fopen(&oc->pb,filename,URL_WRONLY) < 0)	    throw new CImgIOException("unable to open file");    }    if (av_write_header(oc) < 0)	throw new CImgIOException("could not write header");        double video_pts;    SwsContext *img_convert_context = NULL;    img_convert_context = sws_getContext(width,height,src_pxl_fmt,                                         c->width,c->height,c->pix_fmt,sws_flags,NULL,NULL,NULL);    if (!img_convert_context){	//unable to get swscale context        if (!(fmt->flags & AVFMT_NOFILE))	    url_fclose(oc->pb);        av_free(picture->data);        av_free(picture);        av_free(tmp_pict->data[0]);        av_free(tmp_pict);        avcodec_close(video_str->codec);        av_free(oc);        throw new CImgIOException("unable to get conversion context");    }    int ret=0, out_size;    uint8_t *video_outbuf = NULL;    int video_outbuf_size = 1000000;    video_outbuf = (uint8_t*)av_malloc(video_outbuf_size);        if (!video_outbuf){	if (!(fmt->flags & AVFMT_NOFILE))	    url_fclose(oc->pb);	av_free(picture->data);        av_free(picture);        av_free(tmp_pict->data[0]);        av_free(tmp_pict);        avcodec_close(video_str->codec);        av_free(oc);        throw new CImgIOException("mem alloc error");    }    //loop through each image in list    for (unsigned int i = 0; i < pImList->size; i++)    {	frame_count++;        CImg<uint8_t> currentIm = pImList->at(i);	CImg<uint8_t> red,green,blue,gray;	if (src_pxl_fmt == PIX_FMT_RGB24){	    red = currentIm.get_channel(0);	    green = currentIm.get_channel(1);	    blue = currentIm.get_channel(2);            cimg_forXY(red,X,Y){		//assign pizel values to data buffer in interlaced RGBRGB ... format		tmp_pict->data[0][Y*tmp_pict->linesize[0] + 3*X]     = red(X,Y);                tmp_pict->data[0][Y*tmp_pict->linesize[0] + 3*X + 1] = green(X,Y);                tmp_pict->data[0][Y*tmp_pict->linesize[0] + 3*X + 2] = blue(X,Y);	    }	} else {	    gray = currentIm.get_channel(0);	    cimg_forXY(gray,X,Y){                tmp_pict->data[0][Y*tmp_pict->linesize[0] + X] = gray(X,Y);	    }	}	if (video_str)	    video_pts = (video_str->pts.val * video_str->time_base.num)/(video_str->time_base.den);        else	    video_pts = 0.0;        if ((!video_str) || (video_pts >= stream_duration))	    break;	if (sws_scale(img_convert_context,tmp_pict->data,tmp_pict->linesize,0,c->height,picture->data,picture->linesize) < 0){            break;;//break out of loop	}	out_size = avcodec_encode_video(c,video_outbuf,video_outbuf_size,picture);                if (out_size > 0){	    AVPacket pkt;            av_init_packet(&pkt);            pkt.pts = av_rescale_q(c->coded_frame->pts,c->time_base,video_str->time_base);            if (c->coded_frame->key_frame){		pkt.flags |= PKT_FLAG_KEY;	    }            pkt.stream_index = video_str->index;            pkt.data = video_outbuf;            pkt.size = out_size;            ret = av_write_frame(oc,&pkt);	} else if (out_size < 0){            break;//failure occured in avcodec_encode_video() 	}        if (ret != 0){            //error occured in writing frame            break;	}     }    //close codec    if (video_str){	avcodec_close(video_str->codec);        av_free(picture->data[0]);        av_free(picture);        av_free(tmp_pict->data[0]);        av_free(tmp_pict);    }    if (av_write_trailer(oc) < 0)	throw new CImgIOException("could not write trailer");    av_freep(&oc->streams[stream_index]->codec);    av_freep(&oc->streams[stream_index]);    if (!(fmt->flags & AVFMT_NOFILE)){        if (url_fclose(oc->pb) < 0)	    throw new CImgIOException("could not close file");    }    av_free(oc);    av_free(video_outbuf);    return frame_count;}#endif /*CIMGFFMPEG_H_*/

⌨️ 快捷键说明

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