FFmpeg 学习之 解码并 MFC+OpenCV 显示
来源:互联网 发布:快递称重扫描软件 编辑:程序博客网 时间:2024/06/05 08:18
众所周知,Opencv 在图像处理方面具有无与伦比的优势,但其在视频解码这块实在不敢恭维,智能识别 AVI 封装和少数几种 编码格式。
其实 OpenCV 解码也是引用的 FFmpeg,不过编译时估计做了限制。
下面的代码实现的功能是,,FFmpeg 解码视频,然后将每一帧转换为 OpenCV 可以识别的图像格式,在 MFC 图片空间中显示。
配置:VS2008,OpenCV2.4.4,FFmpeg 为11月末的最新版本。
至于工程配置,自己根据实际情况斟酌。
主线程解码存在锁死情况,所以采用了定时器。便于后期的图像处理。
//Dlg.h#pragma once#ifndef INT64_C#define INT64_C(c) (c##LL)#define UINT64_C(c) (c##LL)#endif#ifdef __cplusplusextern "C"{#endif#include "libavformat/avformat.h"#include "libavcodec/avcodec.h"#include "libswscale/swscale.h"#ifdef __cplusplus}#endif#include "cv.h"#include "highgui.h"#include "CvvImage.h"#pragma comment(lib, "swscale.lib")#pragma comment(lib, "avcodec.lib")#pragma comment(lib, "avutil.lib")#pragma comment(lib, "avformat.lib")// CMFC_FFmpegDlg 对话框class CMFC_FFmpegDlg : public CDialog{// 构造public:CMFC_FFmpegDlg(CWnd* pParent = NULL);// 标准构造函数// 对话框数据enum { IDD = IDD_MFC_FFMPEG_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()public:afx_msg void OnBnClickedBload();afx_msg void OnTimer(UINT nIDEvent);public:void DrawPicToHDC(IplImage *img, UINT ID);char * filename;int videoStream;int frameFinished;int numBytes;uint8_t * buffer;AVPacket * packet;AVFrame * pFrameRGB;AVFrame * pFrame;AVCodec * pCodec;AVCodecContext * pCodecCtx;AVFormatContext * pFormatCtx;};
//Dlg.cppvoid CMFC_FFmpegDlg::OnBnClickedBload(){// TODO: 在此添加控件通知处理程序代码CFileDialog dlgFile( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, "视频文件格式AVI file format (*.*)|*.*|", NULL);CString filein; if(dlgFile.DoModal() != IDOK) {filein = ""; return; } filein = dlgFile.GetPathName();filename = (LPSTR)(LPCSTR)filein;AfxMessageBox(filename);av_register_all();avformat_network_init();pFormatCtx = avformat_alloc_context();if(avformat_open_input(&pFormatCtx, filename, NULL, NULL)!=0){AfxMessageBox("open input file faile !");return ;}AfxMessageBox("open input file !"); for(int i=0; i<pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoStream = i; break; }}if(videoStream == -1){AfxMessageBox("could not find video stream !");return ;}AfxMessageBox("find video stream !");pCodecCtx=pFormatCtx->streams[videoStream]->codec;pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { AfxMessageBox("could not find decoder"); return ; }AfxMessageBox("find decoder");if(avcodec_open2(pCodecCtx, pCodec,NULL)<0) { AfxMessageBox("could not open decoder"); return ; }AfxMessageBox("open decoder");av_dump_format(pFormatCtx, 0, filename, 0);pFrame=avcodec_alloc_frame();pFrameRGB=avcodec_alloc_frame();packet=(AVPacket *)av_malloc(sizeof(AVPacket));if(pFrameRGB==NULL){AfxMessageBox("open mem faile");return ;}numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);cvNamedWindow("video", 1);SetTimer(1, 10, NULL);}
//Dlg.cppvoid CMFC_FFmpegDlg::OnTimer(UINT nIDEvent){if(av_read_frame(pFormatCtx, packet)>=0) {if(packet->stream_index==videoStream) {avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);if(frameFinished) {struct SwsContext * img_convert_ctx;img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);if(img_convert_ctx == NULL){AfxMessageBox("Cannot initialize the conversion context !");return ;}static uchar *p = NULL; p = pFrame->data[1];pFrame->data[1] = pFrame->data[2];pFrame->data[2] = p;sws_scale(img_convert_ctx,pFrame->data, pFrame->linesize, 0, pCodecCtx->height,pFrameRGB->data, pFrameRGB->linesize);if (img_convert_ctx){sws_freeContext (img_convert_ctx); img_convert_ctx = NULL;}IplImage * Image;CvSize Size = cvSize(pCodecCtx->width, pCodecCtx->height);Image = cvCreateImage(Size, IPL_DEPTH_8U, 3); memcpy(Image->imageData, buffer, pCodecCtx->width*pCodecCtx->height*24/8);Image->widthStep = pCodecCtx->width*3; Image->origin = 0;cvShowImage("video", Image);DrawPicToHDC(Image, IDC_PIC);UpdateData(FALSE); cvReleaseImage( &Image);}}}}void CMFC_FFmpegDlg::DrawPicToHDC(IplImage *img, UINT ID){CDC *pDC = GetDlgItem(ID)->GetDC(); HDC hDC= pDC->GetSafeHdc(); CRect rect; GetDlgItem(ID)->GetClientRect(&rect); CvvImage cimg; cimg.CopyOf(img,1); cimg.DrawToHDC(hDC,&rect); ReleaseDC(pDC); }
0 0
- FFmpeg 学习之 解码并 MFC+OpenCV 显示
- ffmpeg解码+opencv显示
- FFMpeg视频解码+OpenCV显示
- FFmpeg + Opencv 解码和显示
- ffmpeg解码+opencv显示+时间测试
- ffmpeg解码h264文件,opencv显示
- [ffmpeg]解码并显示
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- ffmpeg和opencv 播放视频文件并显示
- FFmpeg解码H264裸流并转换成opencv Mat
- ffmpeg解码数据转为Mat通过opencv函数显示
- FFmpeg解码-Opencv数据显示-双线程调度
- FFmpeg解码封装为类以及Opencv显示播放
- FFmpeg 学习之 定时器解码两路视频并进行对比
- FFmpeg 学习之 定时器解码两路视频并进行对比<2>
- OpenCV学习笔记之 ( 三 ) MFC显示Mat图片
- MFC 通过opencv 读取并显示图片
- C/C++ static 用法总结
- C# Form.Show()函数的奇怪特性
- house
- android自动化测试MonkeyRunner
- 家居的智能要修炼数据
- FFmpeg 学习之 解码并 MFC+OpenCV 显示
- web开发html css js插件
- atoi,atol,strtod,strtol,strtoul实现类型转换
- LVS+Keepalived实现高可用集群
- 使用 shell 脚本对 Linux 系统和进程资源进行监控
- 上海品牌策划方案要注意的几点技能
- iOS-NSNotification
- hadoop 各个工具原理
- 关于VNC登录的问题,连接只出现一个十字叉