As we all know, OPENCV has unparalleled advantages in image processing, but its video decoding this piece is really not flattering, smart identification AVI package and a few encoding formats.
In fact, OpenCV decoding is also quoted FFmpeg, but compile-time estimates are limited.
The following code implements the function that FFmpeg decodes the video and then converts each frame to a OpenCV recognizable image format that is displayed in the MFC picture space.
Configuration: Vs2008,opencv2.4.4,ffmpeg is the latest version at the end of November.
As for the project configuration, according to the actual situation.
The main thread decoding has a deadlock condition, so the timer is used. Convenient for later image processing.
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 Dialog class Cmfc_ffmpegdlg:public cdialog{//construct Public:cmfc_ffmpegdlg (cwnd* pparent = NULL);//Standard constructor//dialog data enum {IDD = ID D_mfc_ffmpeg_dialog};p rotected:virtual void DoDataExchange (cdataexchange* pDX);//DDX/DDV support//implement Protected:hicon M_ HICON;//generated message map function virtual BOOL OnInitDialog (); afx_msg void OnSysCommand (UINT NID, LPARAM LPARAM); afx_msg void OnPaint (); afx_msg hcursor Onquerydragicon ();D eclare_message_map () public:afx_msg void Onbnclickedbload (); afx_msg void OnTimer ( UINT nidevent);p ublic: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: Add control in this notification handler code CFileDialog dlgfile (TRUE, NULL, NULL, ofn_ hidereadonly | Ofn_overwriteprompt | Ofn_nochangedir, "video file formats 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 ();p formatctx = 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);p frame=avcodec_alloc_frame ();p framergb= Avcodec_alloc_frame ();p acket= (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, ten, 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); Img_convert_ctx = = NULL) {AfxMessageBox ("Cannot initialize the conversion context!"); return;} static Uchar *p = NULL; p = pframe->data[1];p frame->data[1] = pframe->data[2];p frame->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);D rawpictohdc (image, Idc_pic); UpdateData (FALSE); Cvreleaseimage (&image);}}} void Cmfc_ffmpegdlg::D rawpictohdc (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); }
FFmpeg Learning decoding and MFC+OPENCV display