Commit ecb0badb0d3b7ba6b4175c174d63d78e118597e0
1 parent
92989af0
保存jpg图片
Showing
15 changed files
with
863 additions
and
23 deletions
.vscode/launch.json
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | "type": "cppdbg", |
7 | 7 | "request": "launch", |
8 | 8 | "program": "${workspaceFolder}/bin/lib/test", |
9 | - "args": ["rtsp","3", "30012"], | |
9 | + "args": ["rtsp://192.168.10.4:8554/street","3", "30012"], | |
10 | 10 | "stopAtEntry": false, |
11 | 11 | "cwd": "${workspaceFolder}/bin/lib", |
12 | 12 | "environment": [], |
... | ... | @@ -55,6 +55,42 @@ |
55 | 55 | "ignoreFailures": true |
56 | 56 | } |
57 | 57 | ] |
58 | + },{ | |
59 | + "name": "save_tool", | |
60 | + "type": "cppdbg", | |
61 | + "request": "launch", | |
62 | + "program": "${workspaceFolder}/bin/lib/save_tool", | |
63 | + "args": ["rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0"], | |
64 | + "stopAtEntry": false, | |
65 | + "cwd": "${workspaceFolder}/bin/lib", | |
66 | + "environment": [], | |
67 | + "externalConsole": false, | |
68 | + "MIMode": "gdb", | |
69 | + "setupCommands": [ | |
70 | + { | |
71 | + "description": "Enable pretty-printing for gdb", | |
72 | + "text": "-enable-pretty-printing", | |
73 | + "ignoreFailures": true | |
74 | + } | |
75 | + ] | |
76 | + },{ | |
77 | + "name": "gb28181", | |
78 | + "type": "cppdbg", | |
79 | + "request": "launch", | |
80 | + "program": "${workspaceFolder}/bin/lib/test", | |
81 | + "args": ["rtsp://192.168.10.4:8554/street","3", "30026","sipId"], | |
82 | + "stopAtEntry": false, | |
83 | + "cwd": "${workspaceFolder}/bin/lib", | |
84 | + "environment": [], | |
85 | + "externalConsole": false, | |
86 | + "MIMode": "gdb", | |
87 | + "setupCommands": [ | |
88 | + { | |
89 | + "description": "Enable pretty-printing for gdb", | |
90 | + "text": "-enable-pretty-printing", | |
91 | + "ignoreFailures": true | |
92 | + } | |
93 | + ] | |
58 | 94 | } |
59 | 95 | ] |
60 | 96 | } |
61 | 97 | \ No newline at end of file | ... | ... |
src/Makefile renamed to build/Makefile
... | ... | @@ -16,6 +16,7 @@ TARGET= $(DEPEND_DIR)/lib/test |
16 | 16 | |
17 | 17 | SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release |
18 | 18 | JRTP_ROOT = $(THIRDPARTY_ROOT)/jrtp_export |
19 | +CURL_ROOT = $(THIRDPARTY_ROOT)/curl/bin | |
19 | 20 | |
20 | 21 | |
21 | 22 | INCLUDE= -I $(DEPEND_DIR)/include \ |
... | ... | @@ -26,13 +27,15 @@ INCLUDE= -I $(DEPEND_DIR)/include \ |
26 | 27 | -I $(SPDLOG_ROOT)/include \ |
27 | 28 | -I $(SRC_ROOT)/gb28181 \ |
28 | 29 | -I $(JRTP_ROOT)/jrtplib/include/jrtplib3 \ |
29 | - -I $(JRTP_ROOT)/jthread/include/jthread | |
30 | + -I $(JRTP_ROOT)/jthread/include/jthread \ | |
31 | + -I $(CURL_ROOT)/include \ | |
30 | 32 | |
31 | 33 | LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ |
32 | 34 | -L $(CUDA_ROOT)/lib64 -lcuda -lcudart -lnvcuvid -lcurand -lcublas -lnvjpeg \ |
33 | 35 | -L $(SPDLOG_ROOT) -l:libspdlog.a \ |
34 | 36 | -L $(JRTP_ROOT)/jthread/lib -l:libjthread.a \ |
35 | - -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a | |
37 | + -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a \ | |
38 | + -L $(CURL_ROOT)/lib -l:libcurl.a \ | |
36 | 39 | |
37 | 40 | CFLAGS= -g -fPIC -O0 $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl |
38 | 41 | # -DUNICODE -D_UNICODE | ... | ... |
nv-codec-headers/Makefile
save_tool/Makefile
0 → 100644
1 | + | |
2 | +XX = g++ | |
3 | +NVCC = nvcc | |
4 | + | |
5 | +PROJECT_ROOT= /mnt/data/cmhu/FFNvDecoder | |
6 | + | |
7 | +DEPEND_DIR = $(PROJECT_ROOT)/bin | |
8 | +SRC_ROOT = $(PROJECT_ROOT)/save_tool | |
9 | +CUDA_ROOT = /usr/local/cuda | |
10 | + | |
11 | +TARGET= $(DEPEND_DIR)/lib/save_tool | |
12 | + | |
13 | + | |
14 | +INCLUDE= -I $(DEPEND_DIR)/include \ | |
15 | + -I $(CUDA_ROOT)/include \ | |
16 | + -I $(SRC_ROOT)\ | |
17 | + | |
18 | +LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ | |
19 | + -L $(CUDA_ROOT)/lib64 -lcudart -lcurand -lcublas -lnvjpeg \ | |
20 | + -L /usr/lib/wsl/lib -lcuda -lnvcuvid\ | |
21 | + | |
22 | +CFLAGS= -g -fPIC -O0 $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl | |
23 | + # -DUNICODE -D_UNICODE | |
24 | + | |
25 | +NFLAGS_LIB=-g -c -shared -Xcompiler -fPIC -Xcompiler -fvisibility=hidden | |
26 | +NFLAGS = $(NFLAGS_LIB) $(INCLUDE) -std=c++11 | |
27 | + | |
28 | +SRCS:=$(wildcard $(SRC_ROOT)/*.cpp) | |
29 | +OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS))) | |
30 | + | |
31 | +CU_SOURCES = $(wildcard ${SRC_ROOT}/*.cu) | |
32 | +CU_OBJS = $(patsubst %.cu, %.o, $(notdir $(CU_SOURCES))) | |
33 | + | |
34 | + | |
35 | +$(TARGET):$(OBJS) $(CU_OBJS) | |
36 | + rm -f $(TARGET) | |
37 | + $(XX) -o $@ $^ $(CFLAGS) $(LIBSPATH) $(LIBS) -Wwrite-strings | |
38 | + rm -f *.o | |
39 | + | |
40 | +%.o:$(SRC_ROOT)/%.cpp | |
41 | + $(XX) $(CFLAGS) -c $< | |
42 | + | |
43 | +%.o:$(SRC_ROOT)/%.cu | |
44 | + @echo "#######################CU_OBJS:$@###############" | |
45 | + $(NVCC) $(NFLAGS) -o $@ $< | |
46 | + | |
47 | +clean: | |
48 | + rm -f *.o $(TARGET) | |
49 | + | |
50 | + | ... | ... |
save_tool/check_tool.cpp1
0 → 100644
1 | +#include"check_tool.h" | |
2 | + | |
3 | +extern "C" | |
4 | +{ | |
5 | + #include <libavcodec/avcodec.h> | |
6 | + #include <libavdevice/avdevice.h> | |
7 | + #include <libavformat/avformat.h> | |
8 | + #include <libavfilter/avfilter.h> | |
9 | + #include <libavutil/avutil.h> | |
10 | + #include <libavutil/pixdesc.h> | |
11 | + #include <libswscale/swscale.h> | |
12 | + #include <libavutil/imgutils.h> | |
13 | +} | |
14 | + | |
15 | +#include <chrono> | |
16 | + | |
17 | + | |
18 | +static long long get_cur_time(){ | |
19 | + // 获取操作系统当前时间点(精确到微秒) | |
20 | + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro | |
21 | + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); | |
22 | + // (微秒精度的)时间点 => (微秒精度的)时间戳 | |
23 | + time_t currentTime = tpMicro.time_since_epoch().count(); | |
24 | + | |
25 | + return (long long )currentTime; | |
26 | +} | |
27 | + | |
28 | +void save_pkt(const string& uri){ | |
29 | + AVFormatContext* ifmt_ctx = nullptr; | |
30 | + AVCodecContext* codec_ctx = nullptr; | |
31 | + AVCodec *decoder = nullptr; | |
32 | + AVCodec* codec = nullptr; | |
33 | + AVPacket* pkt = nullptr; | |
34 | + int video_index = -1; | |
35 | + AVStream* i_video_stream = nullptr; | |
36 | + SwsContext *img_convert_ctx = nullptr; | |
37 | + uint8_t *buffer = nullptr; | |
38 | + int numBytes = 0; | |
39 | + | |
40 | + long start_time = 0; | |
41 | + long end_time = 0; | |
42 | + long s_time = 0; | |
43 | + long e_time = 0; | |
44 | + long long sum = 0; | |
45 | + double avg_time = 0.0; | |
46 | + | |
47 | + int sep = 0; | |
48 | + | |
49 | + AVFormatContext *o_fmt_ctx; | |
50 | + AVStream *o_video_stream; | |
51 | + | |
52 | + const char *filename = "test.mp4"; | |
53 | + | |
54 | + | |
55 | + avformat_network_init(); | |
56 | + | |
57 | + // 打开输入视频文件 | |
58 | + AVDictionary *options = nullptr; | |
59 | + av_dict_set( &options, "bufsize", "655360", 0 ); | |
60 | + av_dict_set( &options, "rtsp_transport", "tcp", 0 ); | |
61 | + // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s | |
62 | + av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 | |
63 | + | |
64 | + ///打开输入的流 | |
65 | + ifmt_ctx = avformat_alloc_context(); | |
66 | + int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), nullptr, &options); | |
67 | + if (ret != 0){ | |
68 | + av_log(nullptr, AV_LOG_ERROR, "Couldn't open input stream ! \n"); | |
69 | + goto end_flag ; | |
70 | + } | |
71 | + | |
72 | + //查找流信息 | |
73 | + if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0){ | |
74 | + av_log(nullptr, AV_LOG_ERROR, "Couldn't find stream information ! \n"); | |
75 | + goto end_flag ; | |
76 | + } | |
77 | + | |
78 | + // 查找视频流信息 | |
79 | + video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); | |
80 | + if (video_index < 0) { | |
81 | + av_log(nullptr, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n"); | |
82 | + goto end_flag ; | |
83 | + } | |
84 | + | |
85 | + //申请AVCodecContext | |
86 | + codec_ctx = avcodec_alloc_context3(decoder); | |
87 | + if (!codec_ctx){ | |
88 | + goto end_flag ; | |
89 | + } | |
90 | + | |
91 | + i_video_stream = ifmt_ctx->streams[video_index]; | |
92 | + if(avcodec_parameters_to_context(codec_ctx, i_video_stream->codecpar) < 0){ | |
93 | + goto end_flag ; | |
94 | + } | |
95 | + | |
96 | + { | |
97 | + av_log(nullptr, AV_LOG_INFO, "path: %s \n", ifmt_ctx->url); | |
98 | + av_log(nullptr, AV_LOG_INFO, "format: %s \n", ifmt_ctx->iformat->name); | |
99 | + const char* profile = avcodec_profile_name(codec_ctx->codec_id, codec_ctx->profile); | |
100 | + av_log(nullptr, AV_LOG_INFO, "codec: %s(%s) \n", decoder->name, profile); | |
101 | + const char* pix_fmt_name = av_get_pix_fmt_name(codec_ctx->pix_fmt); | |
102 | + av_log(nullptr, AV_LOG_INFO, "pix_fmt_name: %s \n", pix_fmt_name); | |
103 | + av_log(nullptr, AV_LOG_INFO, "width x height: %dX%d \n", i_video_stream->codecpar->width, i_video_stream->codecpar->height); | |
104 | + | |
105 | + av_log(NULL, AV_LOG_INFO, "frame_rate: %1.0f ", av_q2d(i_video_stream->r_frame_rate)); | |
106 | + av_log(NULL, AV_LOG_INFO, " --> reference PPS: %f ms\n", 1/av_q2d(i_video_stream->r_frame_rate) * 1000); | |
107 | + } | |
108 | + | |
109 | + | |
110 | + avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, filename); | |
111 | + | |
112 | + /* | |
113 | + * since all input files are supposed to be identical (framerate, dimension, color format, ...) | |
114 | + * we can safely set output codec values from first input file | |
115 | + */ | |
116 | + o_video_stream = avformat_new_stream(o_fmt_ctx, NULL); | |
117 | + { | |
118 | + AVCodecContext *c; | |
119 | + c = o_video_stream->codec; | |
120 | + c->bit_rate = 400000; | |
121 | + c->codec_id = i_video_stream->codec->codec_id; | |
122 | + c->codec_type = i_video_stream->codec->codec_type; | |
123 | + c->time_base.num = i_video_stream->time_base.num; | |
124 | + c->time_base.den = i_video_stream->time_base.den; | |
125 | + fprintf(stderr, " = time_base.num = %d time_base.den = %d\n", c->time_base.num, c->time_base.den); | |
126 | + c->width = i_video_stream->codec->width; | |
127 | + c->height = i_video_stream->codec->height; | |
128 | + c->pix_fmt = i_video_stream->codec->pix_fmt; | |
129 | + printf(" = width: %d height: %d pix_fmt: %d\n", c->width, c->height, c->pix_fmt); | |
130 | + c->flags = i_video_stream->codec->flags; | |
131 | + c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; | |
132 | + c->me_range = i_video_stream->codec->me_range; | |
133 | + c->max_qdiff = i_video_stream->codec->max_qdiff; | |
134 | + | |
135 | + c->qmin = i_video_stream->codec->qmin; | |
136 | + c->qmax = i_video_stream->codec->qmax; | |
137 | + | |
138 | + c->qcompress = i_video_stream->codec->qcompress; | |
139 | + } | |
140 | + | |
141 | + avio_open(&o_fmt_ctx->pb, filename, AVIO_FLAG_WRITE); | |
142 | + | |
143 | + avformat_write_header(o_fmt_ctx, NULL); | |
144 | + | |
145 | + | |
146 | + s_time = get_cur_time(); | |
147 | + start_time = get_cur_time(); | |
148 | + pkt = av_packet_alloc(); | |
149 | + while (av_read_frame(ifmt_ctx, pkt) >= 0){ | |
150 | + end_time = get_cur_time(); | |
151 | + sum ++ ; | |
152 | + sep ++ ; | |
153 | + if(end_time - start_time > 1000){ | |
154 | + avg_time = double(end_time - start_time) / sep; | |
155 | + start_time = get_cur_time(); | |
156 | + sep = 0; | |
157 | + av_log(nullptr, AV_LOG_INFO, "PPS: %f ms\n", avg_time); | |
158 | + } | |
159 | + av_packet_unref(pkt); | |
160 | + } | |
161 | + | |
162 | + e_time = get_cur_time(); | |
163 | + avg_time = double(e_time - s_time) / sum; | |
164 | + av_log(nullptr, AV_LOG_INFO, "TOOTAL PPS: %f ms\n", avg_time); | |
165 | + | |
166 | +end_flag: | |
167 | + if (codec_ctx != nullptr){ | |
168 | + avcodec_close(codec_ctx); | |
169 | + avcodec_free_context(&codec_ctx); | |
170 | + } | |
171 | + | |
172 | + if (ifmt_ctx != nullptr){ | |
173 | + avformat_close_input(&ifmt_ctx); | |
174 | + } | |
175 | + | |
176 | + if (pkt != nullptr){ | |
177 | + av_packet_free(&pkt); | |
178 | + } | |
179 | +} | |
0 | 180 | \ No newline at end of file | ... | ... |
save_tool/check_tool.h1
0 → 100644
save_tool/main.cpp
0 → 100644
1 | +#include"save_tool.h" | |
2 | + | |
3 | + | |
4 | +#include<iostream> | |
5 | + | |
6 | +using namespace std; | |
7 | + | |
8 | + | |
9 | + | |
10 | +int main(int argc, char *argv[]) { | |
11 | + printf("start \n"); | |
12 | + if (argc != 2) { | |
13 | + fprintf(stderr, "./xxx uri\n"); | |
14 | + return -1; | |
15 | + } | |
16 | + | |
17 | + char* uri = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0"; | |
18 | + | |
19 | + cout << uri << endl; | |
20 | + | |
21 | + save_tool(uri); | |
22 | + | |
23 | + return 0; | |
24 | +} | |
0 | 25 | \ No newline at end of file | ... | ... |
save_tool/save_tool.cpp
0 → 100644
1 | +extern "C" | |
2 | +{ | |
3 | + #include <libavcodec/avcodec.h> | |
4 | + #include <libavdevice/avdevice.h> | |
5 | + #include <libavformat/avformat.h> | |
6 | + #include <libavfilter/avfilter.h> | |
7 | + #include <libavutil/avutil.h> | |
8 | + #include <libavutil/pixdesc.h> | |
9 | + #include <libswscale/swscale.h> | |
10 | + #include <libavutil/imgutils.h> | |
11 | +} | |
12 | + | |
13 | +#include <chrono> | |
14 | +#include<string> | |
15 | + | |
16 | +using namespace std; | |
17 | + | |
18 | +bool bFirstFrame = false; | |
19 | +long last_src_pts = 0; | |
20 | +long last_pts = 0; | |
21 | + | |
22 | +void update_pts(AVPacket* pkt) { | |
23 | + if (pkt->pts > 0) { | |
24 | + if (bFirstFrame) { | |
25 | + bFirstFrame = false; | |
26 | + last_src_pts = pkt->pts; | |
27 | + } | |
28 | + int64_t pkt_pts = pkt->pts; | |
29 | + pkt->pts = last_pts + (pkt_pts - last_src_pts); | |
30 | + last_src_pts = pkt_pts; | |
31 | + last_pts = pkt->pts; | |
32 | + pkt->dts = pkt->pts; | |
33 | + } | |
34 | + else { | |
35 | + if (bFirstFrame) { | |
36 | + bFirstFrame = false; | |
37 | + last_pts = 0; | |
38 | + } | |
39 | + pkt->pts = last_pts + 512; | |
40 | + last_pts = pkt->pts; | |
41 | + } | |
42 | + | |
43 | +} | |
44 | + | |
45 | +void *save_tool(const string uri) | |
46 | +{ | |
47 | + AVFormatContext *i_fmt_ctx; | |
48 | + AVCodecContext* codec_ctx = nullptr; | |
49 | + AVCodec *decoder = nullptr; | |
50 | + AVStream *i_video_stream; | |
51 | + int video_index; | |
52 | + | |
53 | + AVFormatContext *o_fmt_ctx; | |
54 | + AVStream *o_video_stream; | |
55 | + | |
56 | + bool bStop = false; | |
57 | + int frame_nums = 0; | |
58 | + | |
59 | + avcodec_register_all(); | |
60 | + av_register_all(); | |
61 | + avformat_network_init(); | |
62 | + | |
63 | + /* should set to NULL so that avformat_open_input() allocate a new one */ | |
64 | + i_fmt_ctx = NULL; | |
65 | + | |
66 | + const char *filename = "2.mp4"; | |
67 | + | |
68 | + if (avformat_open_input(&i_fmt_ctx, uri.c_str(), NULL, NULL)!=0) | |
69 | + { | |
70 | + fprintf(stderr, " = could not open input file\n"); | |
71 | + return nullptr; | |
72 | + } | |
73 | + | |
74 | + if (avformat_find_stream_info(i_fmt_ctx, NULL)<0) | |
75 | + { | |
76 | + fprintf(stderr, " = could not find stream info\n"); | |
77 | + return nullptr; | |
78 | + } | |
79 | + | |
80 | + video_index = av_find_best_stream(i_fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); | |
81 | + if (video_index < 0) { | |
82 | + av_log(nullptr, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n"); | |
83 | + return nullptr; | |
84 | + } | |
85 | + | |
86 | + codec_ctx = avcodec_alloc_context3(decoder); | |
87 | + if (!codec_ctx){ | |
88 | + return nullptr; | |
89 | + } | |
90 | + | |
91 | + i_video_stream = i_fmt_ctx->streams[video_index]; | |
92 | + if(avcodec_parameters_to_context(codec_ctx, i_video_stream->codecpar) < 0){ | |
93 | + return nullptr; | |
94 | + } | |
95 | + | |
96 | + avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, filename); | |
97 | + | |
98 | + o_video_stream = avformat_new_stream(o_fmt_ctx, NULL); | |
99 | + { | |
100 | + AVCodecContext *c; | |
101 | + c = o_video_stream->codec; | |
102 | + c->bit_rate = 400000; | |
103 | + c->codec_id = i_video_stream->codec->codec_id; | |
104 | + c->codec_type = i_video_stream->codec->codec_type; | |
105 | + c->time_base.num = i_video_stream->time_base.num; | |
106 | + c->time_base.den = i_video_stream->time_base.den; | |
107 | + fprintf(stderr, " = time_base.num = %d time_base.den = %d\n", c->time_base.num, c->time_base.den); | |
108 | + c->width = i_video_stream->codec->width; | |
109 | + c->height = i_video_stream->codec->height; | |
110 | + c->pix_fmt = i_video_stream->codec->pix_fmt; | |
111 | + printf(" = width: %d height: %d pix_fmt: %d\n", c->width, c->height, c->pix_fmt); | |
112 | + c->flags = i_video_stream->codec->flags; | |
113 | + c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; | |
114 | + c->me_range = i_video_stream->codec->me_range; | |
115 | + c->max_qdiff = i_video_stream->codec->max_qdiff; | |
116 | + | |
117 | + c->qmin = i_video_stream->codec->qmin; | |
118 | + c->qmax = i_video_stream->codec->qmax; | |
119 | + | |
120 | + c->qcompress = i_video_stream->codec->qcompress; | |
121 | + } | |
122 | + | |
123 | + avio_open(&o_fmt_ctx->pb, filename, AVIO_FLAG_WRITE); | |
124 | + | |
125 | + avformat_write_header(o_fmt_ctx, NULL); | |
126 | + | |
127 | + AVPacket* i_pkt = av_packet_alloc(); | |
128 | + av_init_packet(i_pkt); | |
129 | + | |
130 | + while (av_read_frame(i_fmt_ctx, i_pkt) >= 0){ | |
131 | + | |
132 | + update_pts(i_pkt); | |
133 | + | |
134 | + static int num = 1; | |
135 | + printf(" = frame %d\n", num++); | |
136 | + av_interleaved_write_frame(o_fmt_ctx, i_pkt); | |
137 | + | |
138 | + av_packet_unref(i_pkt); | |
139 | + | |
140 | + if(frame_nums > 750){ | |
141 | + break; | |
142 | + } | |
143 | + frame_nums++; | |
144 | + } | |
145 | + | |
146 | + av_packet_free(&i_pkt); | |
147 | + | |
148 | + avformat_close_input(&i_fmt_ctx); | |
149 | + | |
150 | + av_write_trailer(o_fmt_ctx); | |
151 | + | |
152 | + avcodec_close(o_fmt_ctx->streams[0]->codec); | |
153 | + av_freep(&o_fmt_ctx->streams[0]->codec); | |
154 | + av_freep(&o_fmt_ctx->streams[0]); | |
155 | + | |
156 | + avio_close(o_fmt_ctx->pb); | |
157 | + av_free(o_fmt_ctx); | |
158 | + | |
159 | + printf("end. \n"); | |
160 | +} | |
0 | 161 | \ No newline at end of file | ... | ... |
save_tool/save_tool.h
0 → 100644
src/FFNvDecoderManager.cpp
... | ... | @@ -40,6 +40,7 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){ |
40 | 40 | if (bRet) |
41 | 41 | { |
42 | 42 | dec->setName(config.name) ; |
43 | + dec->setSnapTimeInterval(config.snap_time_interval); | |
43 | 44 | decoderMap[config.name] = dec; |
44 | 45 | |
45 | 46 | LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri); | ... | ... |
src/FFNvDecoderManager.h
src/FFSaveImg.cpp
0 → 100644
1 | +#include "FFSaveImg.h" | |
2 | + | |
3 | +extern "C" | |
4 | +{ | |
5 | + #include <libavcodec/avcodec.h> | |
6 | + #include <libavdevice/avdevice.h> | |
7 | + #include <libavformat/avformat.h> | |
8 | + #include <libavfilter/avfilter.h> | |
9 | + #include <libavutil/avutil.h> | |
10 | + #include <libavutil/pixdesc.h> | |
11 | + #include <libswscale/swscale.h> | |
12 | + #include <libavutil/imgutils.h> | |
13 | +} | |
14 | + | |
15 | +int saveJpg(AVFrame *pFrame, const char *out_file) { | |
16 | + | |
17 | + int width = pFrame->width; | |
18 | + int height = pFrame->height; | |
19 | + AVCodecContext *pCodecCtx = NULL; | |
20 | + | |
21 | + AVFormatContext *pFormatCtx = avformat_alloc_context(); | |
22 | + // 设置输出文件格式 | |
23 | + pFormatCtx->oformat = av_guess_format("mjpeg", NULL, NULL); | |
24 | + | |
25 | + // 创建并初始化输出AVIOContext | |
26 | + if (avio_open(&pFormatCtx->pb, out_file, AVIO_FLAG_READ_WRITE) < 0) { | |
27 | + printf("Couldn't open output file."); | |
28 | + return -1; | |
29 | + } | |
30 | + | |
31 | + // 构建一个新stream | |
32 | + AVStream *video_st = avformat_new_stream(pFormatCtx, 0); | |
33 | + if (video_st == NULL) { | |
34 | + return -1; | |
35 | + } | |
36 | + | |
37 | + pCodecCtx = video_st->codec; | |
38 | + pCodecCtx->codec_id = pFormatCtx->oformat->video_codec; | |
39 | + pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; | |
40 | + pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P; | |
41 | + pCodecCtx->width = width; | |
42 | + pCodecCtx->height = height; | |
43 | + | |
44 | + pCodecCtx->time_base = (AVRational) {1, 25}; | |
45 | + | |
46 | + AVCodec *pCodec = avcodec_find_encoder(pCodecCtx->codec_id); | |
47 | + | |
48 | + if (!pCodec) { | |
49 | + printf("Could not find encoder\n"); | |
50 | + return -1; | |
51 | + } | |
52 | + | |
53 | + if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { | |
54 | + printf("Could not open codec."); | |
55 | + return -1; | |
56 | + } | |
57 | + | |
58 | + int ret = avformat_write_header(pFormatCtx, NULL); | |
59 | + if (ret < 0) { | |
60 | + printf("write_header fail\n"); | |
61 | + return -1; | |
62 | + } | |
63 | + | |
64 | + AVPacket* pkt = av_packet_alloc(); | |
65 | + av_init_packet(pkt); | |
66 | + | |
67 | + // 编码数据 | |
68 | + ret = avcodec_send_frame(pCodecCtx, pFrame); | |
69 | + if (ret < 0) { | |
70 | + printf("Could not avcodec_send_frame."); | |
71 | + return -1; | |
72 | + } | |
73 | + | |
74 | + // 得到编码后数据 | |
75 | + ret = avcodec_receive_packet(pCodecCtx, pkt); | |
76 | + if (ret < 0) { | |
77 | + printf("Could not avcodec_receive_packet"); | |
78 | + return -1; | |
79 | + } | |
80 | + | |
81 | + ret = av_write_frame(pFormatCtx, pkt); | |
82 | + | |
83 | + if (ret < 0) { | |
84 | + printf("Could not av_write_frame"); | |
85 | + return -1; | |
86 | + } | |
87 | + | |
88 | + av_frame_free(&pFrame); | |
89 | + av_packet_free(&pkt); | |
90 | + | |
91 | + //Write Trailer | |
92 | + av_write_trailer(pFormatCtx); | |
93 | + | |
94 | + | |
95 | + avcodec_close(pCodecCtx); | |
96 | + avio_close(pFormatCtx->pb); | |
97 | + avformat_free_context(pFormatCtx); | |
98 | + | |
99 | + return 0; | |
100 | +} | |
101 | + | |
102 | +AVFrame* convert2yuv(int width, int height, unsigned char * rgbbuf, AVPixelFormat src_pix_fmt){ | |
103 | + | |
104 | + AVPixelFormat dst_pix_fmt = AV_PIX_FMT_YUV420P; | |
105 | + | |
106 | + AVFrame *pFrameYUV = av_frame_alloc(); | |
107 | + uint8_t *out_buffer = new uint8_t[avpicture_get_size(dst_pix_fmt, width, height)]; | |
108 | + | |
109 | + avpicture_fill((AVPicture *)pFrameYUV, out_buffer, dst_pix_fmt, width, height); | |
110 | + | |
111 | + AVFrame *rgbFrame = av_frame_alloc(); | |
112 | + | |
113 | + avpicture_fill((AVPicture *)rgbFrame, rgbbuf, src_pix_fmt, width, height); | |
114 | + | |
115 | + SwsContext *sws_ctx = sws_getContext( | |
116 | + width, height, src_pix_fmt, | |
117 | + width, height, dst_pix_fmt, | |
118 | + SWS_BILINEAR, NULL, NULL, NULL); | |
119 | + | |
120 | + sws_scale(sws_ctx, rgbFrame->data, rgbFrame->linesize, 0, height, pFrameYUV->data, pFrameYUV->linesize); | |
121 | + sws_freeContext(sws_ctx); | |
122 | + av_frame_free(&rgbFrame); | |
123 | + | |
124 | + pFrameYUV->width = width; | |
125 | + pFrameYUV->height = height; | |
126 | + pFrameYUV->format = dst_pix_fmt; | |
127 | + | |
128 | + return pFrameYUV; | |
129 | +} | |
130 | + | |
131 | +void saveJpg(int width, int height, unsigned char * pData, string file_name){ | |
132 | + AVFrame *pFrame = convert2yuv(width, height, pData, AV_PIX_FMT_BGR24); | |
133 | + saveJpg(pFrame, file_name.c_str()); | |
134 | +} | |
0 | 135 | \ No newline at end of file | ... | ... |
src/FFSaveImg.h
0 → 100644
src/gb28181/FFGB28181Decoder.cpp
... | ... | @@ -173,11 +173,11 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i |
173 | 173 | return; |
174 | 174 | } |
175 | 175 | |
176 | - AVPacket framePacket = {}; | |
177 | - av_init_packet(&framePacket); | |
176 | + AVPacket* pkt = av_packet_alloc(); | |
177 | + av_init_packet(pkt); | |
178 | 178 | |
179 | - framePacket.size = len; | |
180 | - framePacket.data = (uint8_t*)data; | |
179 | + pkt->size = len; | |
180 | + pkt->data = (uint8_t*)data; | |
181 | 181 | |
182 | 182 | if (m_pAVCodecCtx == nullptr) { |
183 | 183 | LOG_INFO("frame data is zero --{}", m_dec_name); |
... | ... | @@ -232,11 +232,12 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i |
232 | 232 | } |
233 | 233 | |
234 | 234 | //开始解码 |
235 | - int ret = avcodec_send_packet(m_pAVCodecCtx, &framePacket); | |
235 | + int ret = avcodec_send_packet(m_pAVCodecCtx, pkt); | |
236 | 236 | if (ret < 0) { |
237 | 237 | //send_exception(RunMessageType::E2002, e_msg); |
238 | 238 | LOG_ERROR("Real stream视频解码失败,请检查视频设备{}: avcodec_send_packet failed. ret={}", m_dec_name, ret); |
239 | - av_packet_unref(&framePacket); | |
239 | + av_packet_free(&pkt); | |
240 | + pkt = nullptr; | |
240 | 241 | return; |
241 | 242 | } |
242 | 243 | |
... | ... | @@ -245,7 +246,8 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i |
245 | 246 | frameH = m_pAVCodecCtx->height; |
246 | 247 | if (frameW <= 0 || frameH <= 0) { |
247 | 248 | LOG_ERROR("[{}] frame W or H is error! ({},{})", m_dec_name, frameW, frameH); |
248 | - av_packet_unref(&framePacket); | |
249 | + av_packet_free(&pkt); | |
250 | + pkt = nullptr; | |
249 | 251 | return; |
250 | 252 | } |
251 | 253 | } |
... | ... | @@ -257,16 +259,20 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i |
257 | 259 | ret = avcodec_receive_frame(m_pAVCodecCtx, gpuFrame); |
258 | 260 | if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){ |
259 | 261 | LOG_ERROR("{} - Failed to receive frame: {}", m_dec_name, ret); |
260 | - av_packet_unref(&framePacket); | |
262 | + av_packet_free(&pkt); | |
263 | + pkt = nullptr; | |
261 | 264 | av_frame_free(&gpuFrame); |
265 | + gpuFrame = nullptr; | |
262 | 266 | return; |
263 | 267 | } |
264 | 268 | |
265 | - av_packet_unref(&framePacket); | |
269 | + av_packet_free(&pkt); | |
270 | + pkt = nullptr; | |
266 | 271 | |
267 | 272 | if (gpuFrame->width != frameW || gpuFrame->height != frameH){ |
268 | 273 | LOG_INFO("AVFrame is inconsistent: width is {}, height is {}; original frameW is {}, frameH is {}--{}", gpuFrame->width, gpuFrame->height, frameW, frameH , m_dec_name); |
269 | 274 | av_frame_free(&gpuFrame); |
275 | + gpuFrame = nullptr; | |
270 | 276 | return; |
271 | 277 | } |
272 | 278 | |
... | ... | @@ -275,6 +281,7 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i |
275 | 281 | mFrameQueue.push(gpuFrame); |
276 | 282 | }else{ |
277 | 283 | av_frame_free(&gpuFrame); |
284 | + gpuFrame = nullptr; | |
278 | 285 | } |
279 | 286 | m_queue_mutex.unlock(); |
280 | 287 | } |
... | ... | @@ -297,6 +304,7 @@ void FFGB28181Decoder::post_decode_thread(){ |
297 | 304 | } |
298 | 305 | |
299 | 306 | av_frame_free(&gpuFrame); |
307 | + gpuFrame = nullptr; | |
300 | 308 | |
301 | 309 | index++; |
302 | 310 | if(index >= 100000){ | ... | ... |
src/main.cpp
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | |
13 | 13 | #include <unistd.h> |
14 | 14 | |
15 | +#include "FFSaveImg.h" | |
15 | 16 | |
16 | 17 | #ifdef _WIN32 |
17 | 18 | #include "Winsock2.h" |
... | ... | @@ -24,6 +25,9 @@ |
24 | 25 | |
25 | 26 | #include "utiltools.hpp" |
26 | 27 | |
28 | +#include "curl/curl.h" | |
29 | + | |
30 | + | |
27 | 31 | #define MIN_RTP_PORT 10000 |
28 | 32 | #define MAX_RTP_PORT 60000 |
29 | 33 | |
... | ... | @@ -155,10 +159,34 @@ int CheckCUDAProperty( int devId ) |
155 | 159 | return 0; |
156 | 160 | } |
157 | 161 | |
162 | +static long get_cur_time_ms() { | |
163 | + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro | |
164 | + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); | |
165 | + return tpMicro.time_since_epoch().count(); | |
166 | +} | |
167 | + | |
158 | 168 | /** |
159 | 169 | * 注意: gpuFrame 在解码器设置的显卡上,后续操作要十分注意这一点,尤其是多线程情况 |
160 | 170 | * */ |
161 | 171 | void postDecoded(const void * userPtr, AVFrame * gpuFrame){ |
172 | + | |
173 | + // long first_time = get_cur_time_ms(); | |
174 | + // long second_time = 0; | |
175 | + // int a = 1; | |
176 | + // while(true){ | |
177 | + // a = a * 99; | |
178 | + // if(a > 1000000){ | |
179 | + // a = 1; | |
180 | + // } | |
181 | + // second_time = get_cur_time_ms(); | |
182 | + // if(second_time - first_time > 100){ | |
183 | + // break; | |
184 | + // } | |
185 | + // } | |
186 | + // return ; | |
187 | + | |
188 | + // std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
189 | + | |
162 | 190 | AbstractDecoder* decoder = (AbstractDecoder*)userPtr; |
163 | 191 | if (decoder!= nullptr) |
164 | 192 | { |
... | ... | @@ -235,7 +263,8 @@ static int sum = 0; |
235 | 263 | unsigned char *pHwData = nullptr; |
236 | 264 | |
237 | 265 | void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ |
238 | - // std::this_thread::sleep_for(std::chrono::milliseconds(30000)); | |
266 | + | |
267 | + std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
239 | 268 | |
240 | 269 | AbstractDecoder* decoder = (AbstractDecoder*)userPtr; |
241 | 270 | if (decoder!= nullptr) |
... | ... | @@ -287,12 +316,196 @@ void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ |
287 | 316 | } |
288 | 317 | } |
289 | 318 | |
319 | +//get请求和post请求数据响应函数 | |
320 | +size_t req_reply(void *ptr, size_t size, size_t nmemb, void *stream) | |
321 | +{ | |
322 | + //在注释的里面可以打印请求流,cookie的信息 | |
323 | + //cout << "----->reply" << endl; | |
324 | + string *str = (string*)stream; | |
325 | + //cout << *str << endl; | |
326 | + (*str).append((char*)ptr, size*nmemb); | |
327 | + return size * nmemb; | |
328 | +} | |
329 | + | |
330 | +//http POST请求 | |
331 | +CURLcode curl_post_body_getVideoRealStream(const string &url, const string &postParams, string &response, string devid, string ip, string port) | |
332 | +{ | |
333 | + // curl初始化 | |
334 | + CURL *curl = curl_easy_init(); | |
335 | + // curl返回值 | |
336 | + CURLcode res; | |
337 | + if (curl) | |
338 | + { | |
339 | + // set params | |
340 | + //设置curl的请求头 | |
341 | + struct curl_slist* header_list = NULL; | |
342 | + header_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"); | |
343 | + // header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded; charset=UTF-8"); | |
344 | + | |
345 | + header_list = curl_slist_append(header_list, "Accept: application/json"); | |
346 | + header_list = curl_slist_append(header_list, "Content-Type: application/json");//text/html | |
347 | + header_list = curl_slist_append(header_list, "charsets: utf-8"); | |
348 | + | |
349 | + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); | |
350 | + | |
351 | + //不接收响应头数据0代表不接收 1代表接收 | |
352 | + curl_easy_setopt(curl, CURLOPT_HEADER, 0); | |
353 | + | |
354 | + //设置请求为post请求 | |
355 | + // curl_easy_setopt(curl, CURLOPT_POST, 1); | |
356 | + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); | |
357 | + | |
358 | + //设置请求的URL地址 | |
359 | + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | |
360 | + //设置post请求的参数 | |
361 | + // curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postParams.c_str()); | |
362 | + | |
363 | + //设置ssl验证 | |
364 | + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); | |
365 | + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); | |
366 | + | |
367 | + //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 | |
368 | + curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); | |
369 | + | |
370 | + string strResult = "{ \ | |
371 | + \"authinfo\": \"hisense|hisense123|201807311630\", \ | |
372 | + \"method\": \"getVideoRealStream\", \ | |
373 | + \"deviceId\": \""+devid+"\", \ | |
374 | + \"streamFormat\": \"0\", \ | |
375 | + \"recvIp\": \""+ip+"\", \ | |
376 | + \"recvPort\": \""+port+"\", \ | |
377 | + \"remark\": \"\", \ | |
378 | + \"protocol\": \"1\" \ | |
379 | + }"; | |
380 | + | |
381 | + curl_easy_setopt(curl,CURLOPT_POSTFIELDS,strResult.c_str()); | |
382 | + | |
383 | + curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); | |
384 | + | |
385 | + //设置数据接收和写入函数 | |
386 | + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); | |
387 | + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); | |
388 | + | |
389 | + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); | |
390 | + | |
391 | + //设置超时时间 | |
392 | + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 6); | |
393 | + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6); | |
394 | + | |
395 | + // 开启post请求 | |
396 | + res = curl_easy_perform(curl); | |
397 | + } | |
398 | + //释放curl | |
399 | + curl_easy_cleanup(curl); | |
400 | + return res; | |
401 | +} | |
402 | + | |
403 | +//http POST请求 | |
404 | +CURLcode curl_post_body_stopVideoRealStream(const string &url, const string &postParams, string &response, string handleId) | |
405 | +{ | |
406 | + | |
407 | + // curl初始化 | |
408 | + CURL *curl = curl_easy_init(); | |
409 | + // curl返回值 | |
410 | + CURLcode res; | |
411 | + if (curl) | |
412 | + { | |
413 | + // set params | |
414 | + //设置curl的请求头 | |
415 | + struct curl_slist* header_list = NULL; | |
416 | + header_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"); | |
417 | + // header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded; charset=UTF-8"); | |
418 | + | |
419 | + header_list = curl_slist_append(header_list, "Accept: application/json"); | |
420 | + header_list = curl_slist_append(header_list, "Content-Type: application/json");//text/html | |
421 | + header_list = curl_slist_append(header_list, "charsets: utf-8"); | |
422 | + | |
423 | + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); | |
424 | + | |
425 | + //不接收响应头数据0代表不接收 1代表接收 | |
426 | + curl_easy_setopt(curl, CURLOPT_HEADER, 0); | |
427 | + | |
428 | + //设置请求为post请求 | |
429 | + // curl_easy_setopt(curl, CURLOPT_POST, 1); | |
430 | + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); | |
431 | + | |
432 | + //设置请求的URL地址 | |
433 | + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | |
434 | + //设置post请求的参数 | |
435 | + // curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postParams.c_str()); | |
436 | + | |
437 | + //设置ssl验证 | |
438 | + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); | |
439 | + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); | |
440 | + | |
441 | + //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 | |
442 | + curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); | |
443 | + | |
444 | + string strResult = "{ \ | |
445 | + \"authinfo\": \"hisense|hisense123|201807311630\", \ | |
446 | + \"method\": \"stopVideoRealStream\", \ | |
447 | + \"handleId\": \""+ handleId + "\" \ | |
448 | + }"; | |
449 | + | |
450 | + curl_easy_setopt(curl,CURLOPT_POSTFIELDS,strResult.c_str()); | |
451 | + | |
452 | + curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); | |
453 | + | |
454 | + //设置数据接收和写入函数 | |
455 | + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); | |
456 | + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); | |
457 | + | |
458 | + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); | |
459 | + | |
460 | + //设置超时时间 | |
461 | + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 6); | |
462 | + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6); | |
463 | + | |
464 | + // 开启post请求 | |
465 | + res = curl_easy_perform(curl); | |
466 | + } | |
467 | + //释放curl | |
468 | + curl_easy_cleanup(curl); | |
469 | + return res; | |
470 | +} | |
471 | + | |
290 | 472 | void decode_finished_cbk(const void* userPtr){ |
291 | 473 | cout << "当前时间戳: " << UtilTools::get_cur_time_ms() << endl; |
292 | 474 | } |
293 | 475 | |
476 | +string recv_port = "13012"; | |
477 | + | |
294 | 478 | bool decode_request_stream_cbk(const char* deviceId){ |
295 | - cout << "需在此请求流" << endl; | |
479 | + // cout << "需在此请求流" << endl; | |
480 | + | |
481 | + string url_post = "http://172.16.6.129:7000/httpRequest"; | |
482 | + string paramsLogin = "key1=value1&key2=value2"; | |
483 | + string resPost; | |
484 | + | |
485 | + static string last_handleid = ""; | |
486 | + if(!last_handleid.empty()){ | |
487 | + auto res3 = curl_post_body_stopVideoRealStream(url_post, paramsLogin, resPost, last_handleid); | |
488 | + if (res3 == CURLE_OK) | |
489 | + { | |
490 | + cout << resPost << endl; | |
491 | + } | |
492 | + } | |
493 | + | |
494 | + auto res = curl_post_body_getVideoRealStream(url_post, paramsLogin, resPost, deviceId, "172.16.6.129", recv_port); | |
495 | + if (res == CURLE_OK) | |
496 | + { | |
497 | + cout << resPost << endl; | |
498 | + | |
499 | + size_t start = resPost.find_last_of(":") + 3; | |
500 | + size_t end = resPost.find_last_of("\""); | |
501 | + if (start == end){ | |
502 | + return false; | |
503 | + } | |
504 | + last_handleid = resPost.substr(start,end - start); | |
505 | + | |
506 | + cout << last_handleid << endl; | |
507 | + } | |
508 | + | |
296 | 509 | return true; |
297 | 510 | } |
298 | 511 | |
... | ... | @@ -301,7 +514,7 @@ bool decode_request_stream_cbk(const char* deviceId){ |
301 | 514 | // string test_uri = "/home/cmhu/data/output_1920x1080.mp4"; |
302 | 515 | // string test_uri = "rtsp://176.10.0.2:8554/stream"; |
303 | 516 | // string test_uri = "/mnt/f/fiss/test_data/h265.mp4"; |
304 | -string test_uri = "rtsp://176.10.0.4:8554/stream"; | |
517 | +string test_uri = "rtsp://192.168.10.4:8554/street"; | |
305 | 518 | |
306 | 519 | void createDecode(int index, const char* gpu_id){ |
307 | 520 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
... | ... | @@ -312,6 +525,7 @@ void createDecode(int index, const char* gpu_id){ |
312 | 525 | config.cfg.decode_finished_cbk = decode_finished_cbk; |
313 | 526 | config.cfg.force_tcp = true; |
314 | 527 | config.dec_type = DECODER_TYPE_FFMPEG; |
528 | + config.snap_time_interval = 100; | |
315 | 529 | |
316 | 530 | config.cfg.gpuid = gpu_id; |
317 | 531 | // if (index % 2 == 0) |
... | ... | @@ -333,10 +547,10 @@ void createDecode(int index, const char* gpu_id){ |
333 | 547 | pDecManager->startDecodeByName(config.name); |
334 | 548 | } |
335 | 549 | |
336 | -void createGB28181Decode(int index, char* gpu_id, int port){ | |
550 | +void createGB28181Decode(char* devid, char* gpu_id, int port){ | |
337 | 551 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
338 | 552 | MgrDecConfig config; |
339 | - config.name = "dec" + to_string(index); | |
553 | + config.name = devid; | |
340 | 554 | config.cfg.uri = config.name; |
341 | 555 | config.cfg.post_decoded_cbk = postDecoded; |
342 | 556 | config.cfg.decode_finished_cbk = decode_finished_cbk; |
... | ... | @@ -345,8 +559,11 @@ void createGB28181Decode(int index, char* gpu_id, int port){ |
345 | 559 | |
346 | 560 | config.dec_type = DECODER_TYPE_GB28181; |
347 | 561 | config.cfg.port = port;//allocRtpPort(); |
348 | - | |
562 | + | |
349 | 563 | config.cfg.gpuid = gpu_id; |
564 | + config.snap_time_interval = 100; | |
565 | + | |
566 | + recv_port = to_string(port); | |
350 | 567 | |
351 | 568 | AbstractDecoder* decoder = pDecManager->createDecoder(config); |
352 | 569 | if (!decoder) |
... | ... | @@ -366,10 +583,11 @@ void logFF(void *, int level, const char *fmt, va_list ap) |
366 | 583 | |
367 | 584 | int main(int argc, char* argv[]){ |
368 | 585 | |
369 | - test_uri = "rtsp://admin:admin@123456@192.168.60.176:554/cam/realmonitor?channel=1&subtype=0";//argv[1]; | |
586 | + test_uri = argv[1]; | |
370 | 587 | char* gpuid = argv[2]; |
371 | 588 | int port = atoi(argv[3]); |
372 | - cout << test_uri << " gpu_id:" << gpuid << " port:" << port << endl; | |
589 | + char* devId = argv[4]; | |
590 | + cout << test_uri << " gpu_id:" << gpuid << " port:" << port << " devId:" << devId << endl; | |
373 | 591 | |
374 | 592 | // av_log_set_callback(&logFF); |
375 | 593 | |
... | ... | @@ -382,10 +600,20 @@ int main(int argc, char* argv[]){ |
382 | 600 | // cudaSetDevice(atoi(gpuid)); |
383 | 601 | while (true) |
384 | 602 | { |
385 | - std::this_thread::sleep_for(std::chrono::minutes(1)); | |
603 | + std::this_thread::sleep_for(std::chrono::seconds(10)); | |
386 | 604 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
387 | 605 | int count = pDecManager->count(); |
388 | 606 | cout << "当前时间:" << UtilTools::get_cur_time_ms() << " 当前运行路数: " << pDecManager->count() << endl; |
607 | + vector<FFImgInfo*> vec_img = pDecManager->timing_snapshot_all(); | |
608 | + for (auto imgInfo : vec_img){ | |
609 | + auto task_id = imgInfo->dec_name; | |
610 | + | |
611 | + std::string fpath_ori = "./time_snapshot/" + task_id + "_" + std::to_string(imgInfo->timestamp) + ".jpg"; | |
612 | + | |
613 | + saveJpg(imgInfo->width, imgInfo->height, imgInfo->pData, fpath_ori.c_str()); | |
614 | + | |
615 | + pDecManager->releaseFFImgInfo(imgInfo); | |
616 | + } | |
389 | 617 | } |
390 | 618 | |
391 | 619 | return (void*)0; |
... | ... | @@ -413,7 +641,7 @@ int main(int argc, char* argv[]){ |
413 | 641 | break; |
414 | 642 | case 'g': |
415 | 643 | case 'G': |
416 | - createGB28181Decode(i, gpuid, port); | |
644 | + createGB28181Decode(devId, gpuid, port); | |
417 | 645 | i++; |
418 | 646 | break; |
419 | 647 | case 'r': | ... | ... |