將視頻逐幀提取,轉換為圖片保存下來:
源代碼:
#include <cv.h>
#include <highgui.h>
#if 1 //錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一//錯誤一
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#endif
#include "libRtsp2RGB24Sdk.h"
#include "libRtsp2RGB24Header.h"
int nFrameWidth=1920, nFrameHeight=1080;
void SaveFrame(AVPicture pFrameRGB, int width, int height)
{
IplImage * dst = cvCreateImage(cvSize(nFrameWidth,nFrameHeight),8,3);;
LPVOID pMem = (LPVOID)pFrameRGB.data[0];
memcpy(dst->imageData,pMem,nFrameWidth*nFrameHeight*3);
cvSaveImage("D:\\pic.jpg",dst);
}
void main()
{
avcodec_register_all();
av_register_all();
avformat_network_init();
AVFormatContext *pFormatCtx;
#if 1 //錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二//錯誤二
pFormatCtx = avformat_alloc_context(); //必不可少!
#endif
char *filename = "222.mpg"; // "C:\\Users\\HYZ\\Desktop\\2.avi";
avformat_open_input(&pFormatCtx, filename, NULL, 0);
av_find_stream_info(pFormatCtx);
int videoStream=-1;
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)
{
//sInfo.Format("視頻中無視頻解碼器信息");
//return FALSE;
}
AVCodec * pCodec;
AVCodecContext * pCodecCtx;
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (!pCodec)
{
//sInfo.Format("無法找到視頻解碼器");
//return FALSE;
}
avcodec_open2(pCodecCtx, pCodec, NULL); // 打開解碼器
int frameFinished = 0;
AVFrame *pFrame;
pFrame=avcodec_alloc_frame();
AVPacket avPacket;
av_init_packet(&avPacket);
AVPicture pRGBFrame;
avpicture_alloc(&pRGBFrame,PIX_FMT_RGB24,nFrameWidth,nFrameHeight);
SwsContext * pSwsContext;
pSwsContext = sws_getContext(nFrameWidth, nFrameHeight, pCodecCtx->pix_fmt, nFrameWidth, nFrameHeight,
PIX_FMT_BGR24,SWS_FAST_BILINEAR,NULL,NULL,NULL);
while(av_read_frame(pFormatCtx, &avPacket)>=0)
{
if(avPacket.stream_index==videoStream)
{
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &avPacket);//解碼
if(frameFinished>0)
{
sws_scale(pSwsContext, pFrame->data, pFrame->linesize, 0, nFrameHeight, pRGBFrame.data, pRGBFrame.linesize);
}
SaveFrame(pRGBFrame, pCodecCtx->width, pCodecCtx->height); //保存數據
av_free_packet(&avPacket); //釋放
}
}
}
錯誤一:
運行后錯誤提示:
1>111.obj : error LNK2019: 無法解析的外部符號 "void __cdecl av_free_packet(struct AVPacket *)" (?av_free_packet@@YAXPAUAVPacket@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl avcodec_decode_video2(struct AVCodecContext *,struct AVFrame *,int *,struct AVPacket const *)" (?avcodec_decode_video2@@YAHPAUAVCodecContext@@PAUAVFrame@@PAHPBUAVPacket@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl av_read_frame(struct AVFormatContext *,struct AVPacket *)" (?av_read_frame@@YAHPAUAVFormatContext@@PAUAVPacket@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl avpicture_alloc(struct AVPicture *,enum AVPixelFormat,int,int)" (?avpicture_alloc@@YAHPAUAVPicture@@W4AVPixelFormat@@HH@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "void __cdecl av_init_packet(struct AVPacket *)" (?av_init_packet@@YAXPAUAVPacket@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "struct AVFrame * __cdecl avcodec_alloc_frame(void)" (?avcodec_alloc_frame@@YAPAUAVFrame@@XZ),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl avcodec_open2(struct AVCodecContext *,struct AVCodec const *,struct AVDictionary * *)" (?avcodec_open2@@YAHPAUAVCodecContext@@PBUAVCodec@@PAPAUAVDictionary@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "struct AVCodec * __cdecl avcodec_find_decoder(enum AVCodecID)" (?avcodec_find_decoder@@YAPAUAVCodec@@W4AVCodecID@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl av_find_stream_info(struct AVFormatContext *)" (?av_find_stream_info@@YAHPAUAVFormatContext@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl avformat_open_input(struct AVFormatContext * *,char const *,struct AVInputFormat *,struct AVDictionary * *)" (?avformat_open_input@@YAHPAPAUAVFormatContext@@PBDPAUAVInputFormat@@PAPAUAVDictionary@@@Z),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "struct AVFormatContext * __cdecl avformat_alloc_context(void)" (?avformat_alloc_context@@YAPAUAVFormatContext@@XZ),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "int __cdecl avformat_network_init(void)" (?avformat_network_init@@YAHXZ),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "void __cdecl av_register_all(void)" (?av_register_all@@YAXXZ),該符號在函數 _main 中被引用
1>111.obj : error LNK2019: 無法解析的外部符號 "void __cdecl avcodec_register_all(void)" (?avcodec_register_all@@YAXXZ),該符號在函數 _main 中被引用
1>C:\Users\HYZ\Desktop\測試環境集\stream22.exe : fatal error LNK1120: 14 個無法解析的外部命令
解決方法:注釋掉錯誤一,不包含那些頭文件即可。包含太多的文件也會發生無法解析的錯誤,搞不懂。
錯誤二:
運行到avformat_open_input()函數處停止,而且F11也進不去。
彈出錯誤提示框:stream22.exe中的*****處有未經處理的異常:0xc0000005:讀取位置0xccccccccccc時發生訪問沖突
解決方法:分配內存空間即可:這類錯誤一般是內存錯誤導致,重點排查內存分配。