FFMpeg視訊解碼+OpenCV顯示
首先,當然是FFMpeg的一些配置,這裡下載最新的FFMpeg SDK(FFMpeg SDK由兩部分組成:1.include(FFMpeg開發所需標頭檔案),lib(靜態庫) 2.dll動態庫),只需要在http://ffmpeg.zeranoe.com/builds/下載即可,include與lib檔案對應於Dev packages,
其次,OpenCV的一些配置,這裡我也不說了,都是一些include,lib檔案以及dll檔案通常配置方法。
最後,做一個簡單的例項,驗證配置正確與否,也瞭解一下FFMpeg與OpenCV聯合使用的大致流程:
// FFMpeg + OpenCV demo #include <stdio.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #ifdef __cplusplus extern "C" { #endif #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h> #ifdef __cplusplus } #endif #pragma comment(lib, "opencv_core245d.lib") #pragma comment(lib, "opencv_highgui245d.lib") #pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avformat.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib ,"swscale.lib") static void CopyDate(AVFrame *pFrame,int width,int height,int time); static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame); int main (int argc, const char * argv[]) { AVFormatContext *pFormatCtx = NULL; int i, videoStream; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame; AVFrame *pFrameRGB; AVPacket packet; int frameFinished; int numBytes; uint8_t *buffer; // Register all formats and codecs av_register_all(); // Open video file if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0) // if(avformat_open_input(NULL, argv[1], NULL, NULL)!=0) return -1; // Couldn't open file // Retrieve stream information if(av_find_stream_info(pFormatCtx)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error av_dump_format(pFormatCtx, 0, argv[1], false); // Find the first video stream videoStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoStream=i; break; } if(videoStream==-1) return -1; // Didn't find a video stream // Get a pointer to the codec context for the video stream pCodecCtx=pFormatCtx->streams[videoStream]->codec; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) return -1; // Codec not found // Open codec if(avcodec_open2(pCodecCtx, pCodec, 0)<0) return -1; // Could not open codec // Hack to correct wrong frame rates that seem to be generated by some codecs if(pCodecCtx->time_base.num>1000 && pCodecCtx->time_base.den==1) pCodecCtx->time_base.den=1000; // Allocate video frame pFrame=avcodec_alloc_frame(); // Allocate an AVFrame structure pFrameRGB=avcodec_alloc_frame(); if(pFrameRGB==NULL) return -1; // Determine required buffer size and allocate buffer numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); //buffer=malloc(numBytes); buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); // Assign appropriate parts of buffer to image planes in pFrameRGB avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); // Read frames and save first five frames to disk i=0; long prepts = 0; while(av_read_frame(pFormatCtx, &packet)>=0) { // Is this a packet from the video stream? if(packet.stream_index==videoStream) { // Decode video frame avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); // Did we get a video frame? if(frameFinished) { static struct SwsContext *img_convert_ctx; #if 0 // Older removed code // Convert the image from its native format to RGB swscale img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); // function template, for reference int sws_scale(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]); #endif // Convert the image into YUV format that SDL uses if(img_convert_ctx == NULL) { int w = pCodecCtx->width; int h = pCodecCtx->height; img_convert_ctx = sws_getContext(w, h, pCodecCtx->pix_fmt, w, h, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); if(img_convert_ctx == NULL) { fprintf(stderr, "Cannot initialize the conversion context!\n"); exit(1); } } int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); #if 0 // this use to be true, as of 1/2009, but apparently it is no longer true in 3/2009 if(ret) { fprintf(stderr, "SWS_Scale failed [%d]!\n", ret); exit(-1); } #endif // Save the frame to disk if(i++ <= 5) SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); CopyDate(pFrameRGB, pCodecCtx->width, pCodecCtx->height,packet.pts-prepts); prepts = packet.pts; } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); } // Free the RGB image //free(buffer); av_free(buffer); av_free(pFrameRGB); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file av_close_input_file(pFormatCtx); system("Pause"); return 0; } static void CopyDate(AVFrame *pFrame,int width,int height,int time) { if(time <=0 ) time = 1; int nChannels; int stepWidth; uchar* pData; cv::Mat frameImage(cv::Size(width, height), CV_8UC3, cv::Scalar(0)); stepWidth = frameImage.step; nChannels = frameImage.channels(); pData = frameImage.data; for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { pData[i*stepWidth+j*nChannels+0] = pFrame->data[0][i*pFrame->linesize[0]+j*nChannels+2]; pData[i*stepWidth+j*nChannels+1] = pFrame->data[0][i*pFrame->linesize[0]+j*nChannels+1]; pData[i*stepWidth+j*nChannels+2] = pFrame->data[0][i*pFrame->linesize[0]+j*nChannels+0]; } } cv::namedWindow("Video", cv::WINDOW_NORMAL); cv::imshow("Video", frameImage); cv::waitKey(time); } static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) { FILE *pFile; char szFilename[32]; int y; // Open file sprintf(szFilename, "frame%d.ppm", iFrame); pFile=fopen(szFilename, "wb"); if(pFile==NULL) return; // Write header fprintf(pFile, "P6\n%d %d\n255\n", width, height); // Write pixel data for(y=0; y<height; y++) fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile); // Close file fclose(pFile); }
結果:
相關推薦
FFMpeg視訊解碼+OpenCV顯示
雖然OpenCV底層的視訊解碼也是用的FFMpeg,但是自帶的FFMpeg版本過低,其實OpenCV本來就是一個計算機視覺的庫,不是用來進行視訊開發的,所以最好是單獨用FFMpeg進行視訊編解碼,對FFMpeg解碼得到的幀影象利用OpenCV進行處理。參考
android全平臺編譯ffmpeg視訊解碼器實踐
目錄 配置環境 新建decode工程 配置環境 作業系統: ubuntu 16.05 注意: ffmpeg庫的編譯使用的是android-ndk-r10e版本,使用高版本編譯會報錯 而android-studio工程中配合cmake使用的版本則是a
android 基於FFmpeg視訊解碼器
FFmpeg一個集錄制、轉換、音/視訊編碼解碼功能,強大的音訊處理方案,如何在Android平臺上執行? 1 ,接下來我們需要使用ndk去編譯獲取ffmpeg工具庫,生成.so名稱規範化,有了這些庫才可以利用jni使用在我們Android平臺
ffmpeg解碼h264檔案,opencv顯示
H264.h #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <winsock2
FFmpeg(8)-開啟和配置音視訊解碼器(avcodec_find_decoder()、avcodec_alloc_context3())
一.avcodec_find_decoder 獲取解碼器。在使用之前必須保證所用到的解碼器已經註冊,最簡單的就是呼叫avcodec_register_all() 函式,就像之前註冊解封裝器的時候,也要註冊一下。。 AVCodec *avcodec_find_decoder(enum AVCodecID i
視訊編解碼的理論和實踐2:Ffmpeg視訊編解碼
近幾年,視訊編解碼技術在理論及應用方面都取得了重大的進展,越來越多的人想要了解編解碼技術。因此,網易雲信研發工程師為大家進行了歸納梳理,從理論及實踐兩個方面簡單介紹視訊編解碼技術。 相關閱讀推薦 《視訊直播關鍵技術:流暢、擁塞和延時追趕》 《視訊直播技術詳解:直播的推流
FFMPEG音視訊解碼流程&MP4音視訊檔案流讀取(轉)
1.播放多媒體檔案步驟 通常情況下,我們下載的視訊檔案如MP4,MKV、FLV等都屬於封裝格式,就是把音視訊資料按照相應的規範,打包成一個文字檔案。我們可以使用MediaInfo這個工具檢視媒體檔案的相關資訊。 所以當我們播放一個媒體檔案時,通常需要經過以下幾個步驟
ffmpeg的那點小事兒--ffmpeg的匯入和視訊解碼,YUV儲存(ffmpeg4.0.2)
一、ffmpeg開發的基本知識瞭解 第一點:一個視訊播放流程 通常看到視訊格式:mp4、mov、flv、wmv等等… 稱之為:封裝格式 第二點:視訊播放器 兩種模
【OpenCV開發】OpenCV:使用VideoCapture類進行視訊讀取和顯示
註釋比較詳盡,相信大家都能看得懂,這裡再做幾點補充: 1.由於原視訊是網路攝像頭採集的,所以有很多雪花點,在這裡進行了簡單的均值濾波處理。 2.雖然VideoCapture類中有grab(捕獲下一幀)和retrieve(對該幀進行解碼)操作,但是直接用read比較簡單。 3.get函式的功能很強大,
ffmpeg系列之兩種視訊解碼方式
方式一: #include "myplayer.h" #include <QtWidgets/QApplication> #pragma comment(lib,"avformat.lib") #pragma comment(lib,"avutil.lib")
一個純粹的視訊解碼程式(基於FFMPEG 4.0,在Ubuntu 14.04下驗證)
程式功能:將指定的視訊檔案,解碼為原始YUV資料,只包含視訊流。開發環境:Ubuntu 14.04, GCC 4.8.4, FFMPEG 4.0編譯方法: 將程式碼copy命名為SimpleDecoder.c,與Makefile放置於同一目錄下,執行 make 即可。執行方法
Live555+FFMPEG+ddraw實現H264碼流接收,解碼,顯示
1)H264碼流接收採用的是live555,live555會將sps,pps,I幀,p幀都是單獨的包過來的,在接收到Buffer,需要對它進行組成幀,live555自己支援I幀和P幀的組幀的,但是我們交給ffmpeg前,必須對在每幀之前插入00 00 00 01開始碼,同時
用opencv顯示一張影象和播放一段視訊,寫入視訊到檔案
#include "mainwindow.h" #include <QApplication> #include <iostream> #include <string> #include <sstream> us
海康網路攝像機視訊資料的獲取及使用opencv顯示
最近要使用海康威視攝像機獲取資料做處理。主要是藉助Opencv這個工具,所以做了一下步驟。 我用的是基於Qt+opencv的來顯示海康資料的。本人海康的型號為:DS-2CD2820FD 1、海康sdk開發環境的配置(我只給出我的配置路徑,視具體情況而定)
FFmpeg音視訊解碼同步播放流程
資料接收後處理流程及階段示意圖:1、接收導資料(Trans Stage)2、新建音、視訊解碼執行緒(Parse Stage)3、將解碼好的資料分別放入佇列(Store Stage)4、使用有序的資料結構
ffmpeg實現H.264視訊解碼-1
▶ ffmpeg是一個優秀的開源多媒體編解碼集合 ▶ ffmpeg的libavcodec完成音視訊的編碼或解碼 ▶ H.264視訊解碼主要由H264.c實現 ▶ H264.c能夠流暢解碼x264編碼工程的碼流 ▶ ffmpeg的H.264解碼過程包括初始
javaCV開發詳解之2:推流器實現,推本地攝像頭視訊到流媒體伺服器以及攝像頭錄製視訊功能實現(基於javaCV-FFMPEG、javaCV-openCV)
javaCV系列文章: 補充篇: 歡迎大家積極開心的加入討論群 javacpp-ffmpeg: 前言: 本章將在上一章的基礎上,增加視訊推流到流媒體伺服器和視訊錄製的功能; 功能:實現邊播放邊錄製/推流,停止預覽即停止錄製/推流 提示:
opencv 顯示一個圖片/播放視訊
//顯示圖片 #include"highgui.h" int main(int argc,char **argv) { IplImage *img=NULL; char *imgname="E:/實驗/image/1.jpg"; img=cvLoad
RTSP取流+FFmpeg解碼+OpenGL顯示
該DEMO集合RTSP取流、FFmpeg解碼、OpenGL視訊顯示,自己記錄一下,也跟大家分享一下。 該DEMO參考了以下網站: 1、https://github.com/htwahzs/Rts
centos7下視訊解碼播放環境搭建(ffmpeg等庫編譯)
1.軟體環境 作業系統環境:centos7 ffmpeg原始碼: github上的master版本(當前官網的3.4.1版本有bug,在主幹中修復了'x264_bit_depth' undeclared) 2.編譯與安裝 設定環境變數:(可以在/root/.bash