前一段时间用opencv实现了视频倒播,闲着没事跑去看了看opencv里的代码实现,发现里边也是用ffmpeg实现的,里边有单独的三个头文件直接考出来,基本上不需要修改,直接调用里边的一个struct,里边有函数直接调用就行了
那三个头文件分别是cap_ffmpeg_api.hpp,ffmpeg_codecs.hpp,cap_ffmpeg_impl.hpp
别人开源的东西,研究一下还是对自己有很多帮助的,写的挺巧妙的,不过相对于大一点的视频文件就会很慢了,每次都会seek半天去读上一帧
加QQ群一起交流学习音视频开发:476513431
//图片缩放函数
IplImage* MyRisezeImage(IplImage* pRgbImg, double dScale)
{
IplImage* pDesImage;
int nWidth = pRgbImg->width*dScale;
int nHeight = pRgbImg->height*dScale;
pDesImage = cvCreateImage(CvSize(nWidth, nHeight), pRgbImg->depth, pRgbImg->nChannels);
cvResize(pRgbImg, pDesImage, CV_INTER_AREA);
cvReleaseImage(&pRgbImg);
return pDesImage;
}
//main函数
#include "ffmpegvideoseek.hpp"
int main(int argc, char* argv[])
{
CvCapture_FFMPEG peg;
peg.init();
peg.open("E:\\mycode\\LiveCompile\\x64\\Release\\Titanic.mkv");
//peg.open("D:\\迅雷下载\\ymz.mkv");
unsigned char* rgb;
int nStep = 0;
int nWidth = 0;
int nHeight = 0;
int nCm = 0;
int i = 0;
int64_t nCount = peg.get_total_frames();
while (1)
{
peg.seek(nCount--);
peg.grabFrame();
peg.retrieveFrame(0, &rgb, &nStep, &nWidth, &nHeight, &nCm);
if (nStep == 0)
{
cout << "is null " << i++ << endl;
continue;
}
IplImage *pRgbImg = cvCreateImage(cvSize(nWidth, nHeight), 8, nCm);
memcpy(pRgbImg->imageData, rgb, nWidth * nCm* nHeight);
IplImage *pImg = MyRisezeImage(pRgbImg, 0.4);
cvShowImage("hello", pImg);
//Mat Img = cvarrToMat(pImg, true);
//DetectFace(Img);
waitKey(1000/40);
cvReleaseImage(&pImg);
}
return 0;
}
源码路径:如果编译不过直接删除除了上面的几个文件和main函数文件的其他源文件即可