-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
161 lines (147 loc) · 5.6 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <stdio.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
extern "C"
{
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavcodec/avcodec.h>
}
using namespace cv;
void testShow()
{
bool CanRun = true;
int result = 0;
namedWindow("recognize", 1);
//* 注册
av_register_all();
AVDictionary * options = NULL;
av_dict_set(&options,"buffer_size","1024000",0);
// av_dict_set(&options,"stimeout","2000000",0);
av_dict_set(&options,"max_delay","500000",0);
av_dict_set(&options,"rtsp_transport","tcp",0);
av_dict_set(&options,"preset","medium",0);
av_dict_set(&options,"tune","zerolatency",0);
//* 打开文件
AVFormatContext* pFormatCtx = NULL;
pFormatCtx = avformat_alloc_context();
// step1: 打开媒体文件,最后2个参数是用来指定文件格式,buffer大小和格式参数,设置成NULL的话,libavformat库会自动去探测它们
result = avformat_open_input(&pFormatCtx, "rtsp://admin:[email protected]:554/1/1", NULL, &options);
if (result != 0) {
printf("open file fail \n");
exit(1);
}
printf("open file succ \n");
// step2: 查找信息流的信息
result = avformat_find_stream_info(pFormatCtx, NULL);
if (result != 0) {
printf("find stream fail \n");
exit(1);
}
printf("find stream succ \n");
// 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;
}
}
// 得到video编码格式
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
// step5: 得到解码器
AVCodec* pCodec = NULL;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
printf("find decoder fail \n");
exit(1);
}
printf("find decoder succ \n");
result = avcodec_open2(pCodecCtx, pCodec, NULL);
if (result != 0) {
printf("open codec fail \n");
exit(1);
}
printf("open codec succ %d \n",pCodecCtx->bit_rate);
// step6: 申请原始数据帧 和 RGB帧内存
AVFrame* pFrame = NULL;
AVFrame* pFrameRGB = NULL;
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
if (pFrame == NULL || pFrameRGB == NULL) {
return;
}
int numBytes = avpicture_get_size(AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);
uint8_t* buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture*)pFrameRGB, buffer, AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);
int frameFinishsed = 0;
AVPacket packet;
i = 0;
printf("step6 succ \n");
// step7: 创建格式转化文本
struct SwsContext *pSwxCtx = sws_getContext(
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_BGR24,
SWS_BILINEAR, 0, 0, 0);
printf("step7 succ \n");
unsigned char *rgbBuf;
rgbBuf = (unsigned char *)malloc( pCodecCtx->width * pCodecCtx->height * 3 * sizeof(unsigned char));
unsigned char *tmp;
tmp = (unsigned char *)malloc( pCodecCtx->width * pCodecCtx->height * 3 * sizeof(unsigned char));
//IplImage* img = cvCreateImage(cvSize(pCodecCtx->width,pCodecCtx->height),IPL_DEPTH_8U,3);
IplImage* img = cvCreateImage(cvSize(pCodecCtx->width,pCodecCtx->height),IPL_DEPTH_8U,3);
Mat mat_img = Mat(pCodecCtx->height,pCodecCtx->width, CV_8UC3);
int frame_rate = 25;
if(pFormatCtx->streams[videoStream]->r_frame_rate.den>0){
frame_rate = pFormatCtx->streams[videoStream]->r_frame_rate.num/pFormatCtx->streams[videoStream]->r_frame_rate.den;
}else if(pCodecCtx->framerate.den>0){
frame_rate = pCodecCtx->framerate.num/pCodecCtx->framerate.den;
}
printf("width:%d height %d frame rate %d\n",pCodecCtx->width,pCodecCtx->height,frame_rate);
int skipped_frame = 0;
av_init_packet(&packet);
while (av_read_frame(pFormatCtx, &packet)>=0) {
++skipped_frame;
if(skipped_frame>10000){
break;
}
if (packet.stream_index == videoStream) {
// 解码
result = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinishsed, &packet);
if (frameFinishsed) {
// 转换
sws_scale(pSwxCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, &rgbBuf, pFrameRGB->linesize);
//img->imageData = (char*)rgbBuf;
//img->imageDataOrigin = (char*)rgbBuf;
//img->imageData = (char*)rgbBuf;
//img->imageDataOrigin = (char*)rgbBuf;
//Mat img_kepur = imread("./kepur.jpg");
mat_img.data = rgbBuf;
imshow("recognize", mat_img);//img
//cvWaitKey(1000/frame_rate);
waitKey(1);
// savejpg(rgbBuf, i, pCodecCtx->width, pCodecCtx->height);//生成图片
// if(i>3){
// break;
// }
}else{
//skipped_frame++;
}
}
av_free_packet(&packet);
}
avformat_close_input(&pFormatCtx);
printf("Hello world!! .\n");
}
int main(){
testShow();
return 0;
}