ffmpeg opencv 打开视频文件,并且播放
// FFMpeg + OpenCV demo
#include
#include
#include #ifdef __cplusplus
extern "C" {
#endif#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include #ifdef __cplusplus
}
#endif#include static void CopyDate(AVFrame *pFrame, int width, int height, int time);
static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
int result = 0;
av_register_all();
// 注册所有FFmpeg库所支持的文件格式和codec AVFormatContext* pFormatCtx;
char* filename = "up.mp4";
//输入文件名 // step1: 打开媒体文件,最后2个参数是用来指定文件格式,buffer大小和格式参数,设置成NULL的话,libavformat库会自动去探测它们
result = avformat_open_input(&pFormatCtx, filename, NULL, NULL);
if (result != 0)
{
cout << "open file fail" << endl;
return -1;
}
cout << "open file succ" << endl;
// step2: 查找信息流的信息
result = avformat_find_stream_info(pFormatCtx, NULL);
if (result != 0)
{
cout << "find stream fail" << endl;
return -1;
}
cout << "find stream succ" << endl;
// step3: 打印信息
//av_dump_format(pFormatCtx, 0, filename, 0);
// step4:找到video流数据
int i = 0;
int videoStream = -1;
AVCodecContext* pCodecCtx = NULL;
for (i = 0;
i < pFormatCtx->nb_streams;
i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
break;
}
} if (videoStream == -1)
{
cout << "find stream video fail" << endl;
return -1;
}
cout << "find stream video succ." << endl;
// 得到video编码格式
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
// step5: 得到解码器
AVCodec* pCodec = NULL;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
{
cout << "find decoder fail" << endl;
return -1;
}
cout << "find decoder succ" << endl;
result = avcodec_open2(pCodecCtx, pCodec, NULL);
if (result != 0)
{
cout << "open codec fail" << endl;
return -1;
}
cout << "open codec succ" << endl;
// step6: 申请原始数据帧 和 RGB帧内存
AVFrame* pFrame = NULL;
AVFrame* pFrameRGB = NULL;
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
if (pFrame == NULL || pFrameRGB == NULL)
{
return -1;
} int numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
uint8_t* buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture*)pFrameRGB, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
int frameFinishsed = 0;
AVPacket packet;
i = 0;
// step7: 创建格式转化文本
SwsContext * pSwxCtx = sws_getContext(
pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24,
SWS_BILINEAR, 0, 0, 0);
cv::Mat image(pCodecCtx->height, pCodecCtx->width, CV_8UC3);
int b = 0;
int g = 1;
int r = 2;
while (true)
{
// 得到数据包
result = av_read_frame(pFormatCtx, &packet);
if (result != 0)
{
break;
}if (packet.stream_index == videoStream)
{
// 解码
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinishsed, &packet);
if (frameFinishsed)
{
// 转换
sws_scale(pSwxCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameRGB->data, pFrameRGB->linesize);
for (int m = 0;
m < pCodecCtx->height;
m++)
{
for (int n = 0;
n < pCodecCtx->width;
n++)
{
image.at(m, n)[r] = pFrameRGB->data[0][3 * (m*pCodecCtx->width + n) + 0];
image.at(m, n)[g] = pFrameRGB->data[0][3 * (m*pCodecCtx->width + n) + 1];
image.at(m, n)[b] = pFrameRGB->data[0][3 * (m*pCodecCtx->width + n) + 2];
}
}
cv::imshow("pic", image);
cv::waitKey(30);
}
}av_free_packet(&packet);
}
avformat_close_input(&pFormatCtx);
system("pause");
return 0;
}
【ffmpeg opencv 打开视频文件,并且播放】
文章图片
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- Java|Java OpenCV图像处理之SIFT角点检测详解
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 【70号】Day26朋友日
- 分享!如何分分钟实现微信扫二维码调用外部浏览器打开指定页面的功能
- [成长]“青椒”给我打开了一扇窗——我的青椒学习之旅
- ffmpeg源码分析01(结构体)
- 你有跟人打过架吗()
- 思维导图让你换一种打开方式学数学
- 花时间做自己