opencv的highgui显示ffmpeg的数据

11 篇文章 0 订阅
9 篇文章 0 订阅


ffmpeg是一个强大的开源的编解码用的库,功能及其强大,但是由于其官方的文档少的可怜,例子少的可怜十分不利于普通初学者学习。我有opencv的基础,opencv的highgui做的界面虽然简单,但是代码也简单。在我不断的探索下,终于可以使用opencv的界面来显示ffmpeg的处理结果了。

下面的ffmpeg代码是参考:http://blog.csdn.net/jia_zhengshen/article/details/10334313来写的,opencv部分有注释。

但是注意程序没有进行内存的清理,所以嘛,如果影片的很大的话,哈哈,你的内存完蛋了。

http://abowman-dog-gadget.googlecode.com/svn/trunk/dog.swf

#include<opencv\cv.h>
#include<opencv\highgui.h>
#ifdef  __cplusplus  
extern "C" {  
#endif  
#include<avcodec.h>
#include<avformat.h>
#include<libswscale\swscale.h>
int main()
{
	IplImage *img ;//= cvCreateImage(
	av_register_all();
	avcodec_register_all();
	avformat_network_init();
	AVFormatContext *pFormatCtx = NULL;
	char *filename = "test.flv";
	if( avformat_open_input(&pFormatCtx,filename,NULL,NULL) !=	0)
		return 1;
	if( av_find_stream_info(pFormatCtx) <0)
		return 2;
	av_dump_format(pFormatCtx,0,filename,0);
	
	AVCodecContext *pCodecCtx;
	int i=-1;
	int videoStream =-1;
	for(i=0;i<pFormatCtx->nb_streams;i++)
	{
		if(pFormatCtx->streams[i]->codec->codec_type== AVMEDIA_TYPE_VIDEO)
		{
			videoStream = i;
			break;
		}
	}//for
	if(videoStream ==-1)
	{
		return 3;
	}
	pCodecCtx= pFormatCtx->streams[videoStream]->codec;
	AVCodec *pCodec ;
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	if(pCodec ==NULL)
		return 4;
	if(avcodec_open(pCodecCtx,pCodec)<0)
		return 5;
	AVFrame *pFrame ;
	pFrame = avcodec_alloc_frame();
	AVFrame  *pFrameRGB;
	pFrameRGB= avcodec_alloc_frame();
	uint8_t *buffer ;
	int numBytes;
	numBytes = avpicture_get_size(PIX_FMT_RGB24,pCodecCtx->width,
		pCodecCtx->height);
	buffer  = (uint8_t *)av_malloc(numBytes*sizeof(char) );
	avpicture_fill((AVPicture *)pFrameRGB,buffer,PIX_FMT_RGB24,
		pCodecCtx->width,pCodecCtx->height);

	int frameFinished;
	AVPacket packet;
	i=0;
	while(av_read_frame(pFormatCtx,&packet)>=0 )
	{
		if(packet.stream_index == videoStream )
		{
			avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);
			if(frameFinished)
			{
				SwsContext *pSwsCtx;
				pSwsCtx = sws_getContext(pCodecCtx->width,
					pCodecCtx->height,pCodecCtx->pix_fmt,
					pCodecCtx->width,pCodecCtx->height,
					AV_PIX_FMT_BGR24,SWS_POINT,NULL,NULL,NULL
					);
				sws_scale(pSwsCtx,pFrame->data,pFrame->linesize,0,
					pCodecCtx->height,pFrameRGB->data,pFrameRGB->linesize
					);//ffmpeg的从yuv420格式转换到bgr24格式。
				int w = pCodecCtx->width;
				int h = pCodecCtx->height;
				img = cvCreateImageHeader(cvSize(w,h),8,3);
				img->imageData =(char *)(*( pFrameRGB->data) );//把ffmpeg格式转换到opencv的bgr格式。
				cvShowImage("img",img);
				IplImage *imgbgr = cvCreateImage(cvSize(w,h),8,3);
				//cvCvtColor(img,imgbgr,CV_RGB2BGR);
				cvCvtColor(img,imgbgr,CV_BGR2HSV);
				cvShowImage("HSV",imgbgr);
				cvWaitKey(2);
			}//得到了一帧frame
		}//video
	}//while
	printf("tttttt");
}
#ifdef  __cplusplus  
}  
#endif  







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个功能,首先需要安装FFmpegOpenCV库。然后可以按照以下步骤进行操作: 1. 导入头文件 ```c++ #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/videoio.hpp> #include "ffmpeg.h" ``` 2. 定义回调函数 ```c++ void display_frame(cv::Mat frame) { cv::imshow("Video", frame); cv::waitKey(1); } ``` 3. 定义获取视频流的函数 ```c++ void get_stream(const std::string& url) { AVFormatContext* format_ctx = avformat_alloc_context(); AVDictionary* options_dict = NULL; av_dict_set(&options_dict, "rtsp_transport", "tcp", 0); av_dict_set(&options_dict, "stimeout", "5000000", 0); av_dict_set(&options_dict, "max_delay", "500000", 0); av_dict_set(&options_dict, "buffer_size", "1024000", 0); av_dict_set(&options_dict, "rtbufsize", "1024000", 0); av_dict_set(&options_dict, "max_delay", "500000", 0); avformat_open_input(&format_ctx, url.c_str(), NULL, &options_dict); avformat_find_stream_info(format_ctx, NULL); AVCodec* codec = nullptr; int stream_index = av_find_best_stream(format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0); AVCodecContext* codec_ctx = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx, format_ctx->streams[stream_index]->codecpar); avcodec_open2(codec_ctx, codec, NULL); AVPacket* packet = av_packet_alloc(); AVFrame* frame = av_frame_alloc(); while (av_read_frame(format_ctx, packet) >= 0) { if (packet->stream_index == stream_index) { avcodec_send_packet(codec_ctx, packet); while (avcodec_receive_frame(codec_ctx, frame) == 0) { cv::Mat mat(frame->height, frame->width, CV_8UC3, frame->data[0]); cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); display_frame(mat); av_frame_unref(frame); } } av_packet_unref(packet); } av_packet_free(&packet); av_frame_free(&frame); avcodec_close(codec_ctx); avcodec_free_context(&codec_ctx); avformat_close_input(&format_ctx); } ``` 4. 调用函数播放视频流 ```c++ int main() { std::string url = "rtsp://xxx.xxx.xxx.xxx:xxxx/xxx"; get_stream(url); return 0; } ``` 这样就可以获取RTSP视频流并使用OpenCV显示图像了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值