Commit bc52e542d1e046d2f5c24ba363331191f31f08b5
1 parent
f667f79a
添加关键帧解码功能
Showing
6 changed files
with
118 additions
and
45 deletions
.vscode/settings.json
src/FFNvDecoder.cpp
... | ... | @@ -5,6 +5,8 @@ |
5 | 5 | #include <thread> |
6 | 6 | #include <fstream> |
7 | 7 | |
8 | +#include <chrono> | |
9 | + | |
8 | 10 | #include "FFCuContextManager.h" |
9 | 11 | |
10 | 12 | using namespace std; |
... | ... | @@ -45,11 +47,12 @@ FFNvDecoder::FFNvDecoder() |
45 | 47 | m_post_decode_thread = 0; |
46 | 48 | |
47 | 49 | m_bFinished = false; |
50 | + m_dec_keyframe = false; | |
48 | 51 | } |
49 | 52 | |
50 | 53 | FFNvDecoder::~FFNvDecoder() |
51 | 54 | { |
52 | - | |
55 | + m_dec_keyframe = false; | |
53 | 56 | } |
54 | 57 | |
55 | 58 | bool FFNvDecoder::init(FFDecConfig& cfg) |
... | ... | @@ -157,6 +160,18 @@ void FFNvDecoder::start(){ |
157 | 160 | ,this); |
158 | 161 | } |
159 | 162 | |
163 | +static long long get_cur_time(){ | |
164 | + // 获取操作系统当前时间点(精确到微秒) | |
165 | + chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro | |
166 | + = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now()); | |
167 | + // (微秒精度的)时间点 => (微秒精度的)时间戳 | |
168 | + time_t totalMicroSeconds = tpMicro.time_since_epoch().count(); | |
169 | + | |
170 | + long long currentTime = ((long long)totalMicroSeconds)/1000; | |
171 | + | |
172 | + return currentTime; | |
173 | +} | |
174 | + | |
160 | 175 | void FFNvDecoder::decode_thread() |
161 | 176 | { |
162 | 177 | AVPacket* pkt ; |
... | ... | @@ -172,6 +187,8 @@ void FFNvDecoder::decode_thread() |
172 | 187 | } |
173 | 188 | ,this); |
174 | 189 | |
190 | + // long start_time = get_cur_time(); | |
191 | + | |
175 | 192 | while (m_bRunning) |
176 | 193 | { |
177 | 194 | if (!m_bReal) |
... | ... | @@ -202,6 +219,11 @@ void FFNvDecoder::decode_thread() |
202 | 219 | break; |
203 | 220 | } |
204 | 221 | |
222 | + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) { | |
223 | + av_packet_unref(pkt); | |
224 | + continue; | |
225 | + } | |
226 | + | |
205 | 227 | if (m_bReal) |
206 | 228 | { |
207 | 229 | if (m_bPause) |
... | ... | @@ -235,6 +257,10 @@ void FFNvDecoder::decode_thread() |
235 | 257 | |
236 | 258 | m_bRunning = false; |
237 | 259 | |
260 | + // long end_time = get_cur_time(); | |
261 | + | |
262 | + // cout << "解码用时:" << end_time - start_time << endl; | |
263 | + | |
238 | 264 | if (m_post_decode_thread != 0) |
239 | 265 | { |
240 | 266 | pthread_join(m_post_decode_thread,0); |
... | ... | @@ -258,6 +284,7 @@ void FFNvDecoder::decode_finished() |
258 | 284 | } |
259 | 285 | |
260 | 286 | m_bFinished = true; |
287 | + m_dec_keyframe = false; | |
261 | 288 | } |
262 | 289 | |
263 | 290 | void FFNvDecoder::post_decode_thread() |
... | ... | @@ -285,6 +312,7 @@ void FFNvDecoder::close() |
285 | 312 | if(m_decode_thread != 0){ |
286 | 313 | pthread_join(m_decode_thread,0); |
287 | 314 | } |
315 | + m_dec_keyframe = false; | |
288 | 316 | } |
289 | 317 | |
290 | 318 | void FFNvDecoder::setName(string nm){ |
... | ... | @@ -330,4 +358,9 @@ void FFNvDecoder::pause() |
330 | 358 | void FFNvDecoder::resume() |
331 | 359 | { |
332 | 360 | m_bPause = false; |
361 | +} | |
362 | + | |
363 | +void FFNvDecoder::setDecKeyframe(bool bKeyframe) | |
364 | +{ | |
365 | + m_dec_keyframe = bKeyframe; | |
333 | 366 | } |
334 | 367 | \ No newline at end of file | ... | ... |
src/FFNvDecoder.h
... | ... | @@ -47,6 +47,8 @@ public: |
47 | 47 | void pause(); |
48 | 48 | void resume(); |
49 | 49 | |
50 | + void setDecKeyframe(bool bKeyframe); | |
51 | + | |
50 | 52 | bool isRunning(); |
51 | 53 | bool isFinished(); |
52 | 54 | bool getResolution( int &width, int &height ); |
... | ... | @@ -88,4 +90,6 @@ private: |
88 | 90 | FrameQueue mFrameQueue; |
89 | 91 | |
90 | 92 | bool m_bReal; // 是否实时流 |
93 | + | |
94 | + bool m_dec_keyframe; | |
91 | 95 | }; |
92 | 96 | \ No newline at end of file | ... | ... |
src/FFNvDecoderManager.cpp
... | ... | @@ -215,7 +215,7 @@ bool FFNvDecoderManager::isSurport(FFDecConfig& cfg) |
215 | 215 | } |
216 | 216 | |
217 | 217 | bool FFNvDecoderManager::isRunning(const string name){ |
218 | - if (name.empty()) | |
218 | + if (name.empty()) | |
219 | 219 | { |
220 | 220 | cout << "name 为空!"<< endl; |
221 | 221 | return false; |
... | ... | @@ -229,4 +229,23 @@ bool FFNvDecoderManager::isRunning(const string name){ |
229 | 229 | |
230 | 230 | cout << "没有找到name为" << name << "的解码器!" << endl; |
231 | 231 | return false; |
232 | +} | |
233 | + | |
234 | +bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe) | |
235 | +{ | |
236 | + if (name.empty()) | |
237 | + { | |
238 | + cout << "name 为空!"<< endl; | |
239 | + return false; | |
240 | + } | |
241 | + | |
242 | + auto dec = decoderMap.find(name); | |
243 | + if (dec != decoderMap.end()) | |
244 | + { | |
245 | + dec->second->setDecKeyframe(bKeyframe); | |
246 | + return true; | |
247 | + } | |
248 | + | |
249 | + cout << "没有找到name为" << name << "的解码器!" << endl; | |
250 | + return false; | |
232 | 251 | } |
233 | 252 | \ No newline at end of file | ... | ... |
src/FFNvDecoderManager.h
... | ... | @@ -156,6 +156,16 @@ public: |
156 | 156 | **************************************************/ |
157 | 157 | int count(); |
158 | 158 | |
159 | + /************************************************** | |
160 | + * 接口:setDecKeyframe | |
161 | + * 功能:设置是否只解码关键帧。默认全解 | |
162 | + * 参数:const string name 解码器名称 | |
163 | + * bool bKeyframe 是否只解码关键帧。true,只解码关键帧;false,普通的全解码 | |
164 | + * 返回:void | |
165 | + * 备注: | |
166 | + **************************************************/ | |
167 | + bool setDecKeyframe(const string name, bool bKeyframe); | |
168 | + | |
159 | 169 | private: |
160 | 170 | FFNvDecoderManager(){} |
161 | 171 | ... | ... |
src/main.cpp
... | ... | @@ -92,7 +92,7 @@ bool count_flag = false; |
92 | 92 | int count = 0; |
93 | 93 | int count_std = 100; |
94 | 94 | |
95 | -long long get_cur_time(){ | |
95 | +static long long get_cur_time(){ | |
96 | 96 | // 获取操作系统当前时间点(精确到微秒) |
97 | 97 | chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro |
98 | 98 | = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now()); |
... | ... | @@ -104,10 +104,12 @@ long long get_cur_time(){ |
104 | 104 | return currentTime; |
105 | 105 | } |
106 | 106 | |
107 | -int sum = 0; | |
107 | +static int sum = 0; | |
108 | 108 | unsigned char *pHwData = nullptr; |
109 | 109 | |
110 | 110 | void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ |
111 | + // std::this_thread::sleep_for(std::chrono::milliseconds(30000)); | |
112 | + | |
111 | 113 | FFNvDecoder* decoder = (FFNvDecoder*)userPtr; |
112 | 114 | if (decoder!= nullptr) |
113 | 115 | { |
... | ... | @@ -122,44 +124,47 @@ void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ |
122 | 124 | } |
123 | 125 | count++; |
124 | 126 | sum ++ ; |
125 | - if (count >= count_std) | |
126 | - { | |
127 | - end_time = get_cur_time(); | |
128 | - long time_using = end_time - start_time; | |
129 | - double time_per_frame = double(time_using)/count_std ; | |
130 | - cout << count_std << "帧用时:" << time_using << "ms 每帧用时:" << time_per_frame << "ms" << endl; | |
131 | - cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl; | |
132 | - cout << gpuFrame->pts << endl; | |
133 | - | |
134 | - count_flag = false; | |
135 | - } | |
136 | - | |
137 | - if (gpuFrame->format == AV_PIX_FMT_CUDA) | |
138 | - { | |
139 | - cudaSetDevice(atoi(decoder->m_cfg.gpuid.c_str())); | |
140 | - cout << "gpu id : " << decoder->m_cfg.gpuid.c_str() << endl; | |
141 | - cudaError_t cudaStatus; | |
142 | - if(pHwData == nullptr){ | |
143 | - cuda_common::setColorSpace2( ITU709, 0 ); | |
144 | - cudaStatus = cudaMalloc((void **)&pHwData, 3 * gpuFrame->width * gpuFrame->height * sizeof(unsigned char)); | |
145 | - } | |
146 | - cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], pHwData, gpuFrame->width, gpuFrame->height); | |
147 | - cudaDeviceSynchronize(); | |
148 | - if (cudaStatus != cudaSuccess) { | |
149 | - cout << "CUDAToBGR failed !!!" << endl; | |
150 | - return; | |
151 | - } | |
152 | - | |
153 | - string path = "/home/cmhu/data/test/" + to_string(sum) + ".jpg"; | |
154 | - saveJpeg(path.c_str(), pHwData, gpuFrame->width, gpuFrame->height, nullptr); // 验证 CUDAToRGB | |
155 | - } | |
127 | + // if (count >= count_std) | |
128 | + // { | |
129 | + // // end_time = get_cur_time(); | |
130 | + // // long time_using = end_time - start_time; | |
131 | + // // double time_per_frame = double(time_using)/count_std ; | |
132 | + // // cout << count_std << "帧用时:" << time_using << "ms 每帧用时:" << time_per_frame << "ms" << endl; | |
133 | + // cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl; | |
134 | + // cout << gpuFrame->pts << endl; | |
135 | + | |
136 | + // count_flag = false; | |
137 | + // } | |
138 | + // cout << "帧数:" << sum << endl; | |
139 | + | |
140 | + // if (gpuFrame->format == AV_PIX_FMT_CUDA) | |
141 | + // { | |
142 | + // cudaSetDevice(atoi(decoder->m_cfg.gpuid.c_str())); | |
143 | + // // cout << "gpu id : " << decoder->m_cfg.gpuid.c_str() << endl; | |
144 | + // cudaError_t cudaStatus; | |
145 | + // if(pHwData == nullptr){ | |
146 | + // cuda_common::setColorSpace2( ITU709, 0 ); | |
147 | + // cudaStatus = cudaMalloc((void **)&pHwData, 3 * gpuFrame->width * gpuFrame->height * sizeof(unsigned char)); | |
148 | + // } | |
149 | + // cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], pHwData, gpuFrame->width, gpuFrame->height); | |
150 | + // cudaDeviceSynchronize(); | |
151 | + // if (cudaStatus != cudaSuccess) { | |
152 | + // cout << "CUDAToBGR failed !!!" << endl; | |
153 | + // return; | |
154 | + // } | |
155 | + | |
156 | + // string path = "/home/cmhu/data/test/" + to_string(sum) + ".jpg"; | |
157 | + // saveJpeg(path.c_str(), pHwData, gpuFrame->width, gpuFrame->height, nullptr); // 验证 CUDAToRGB | |
158 | + // } | |
156 | 159 | } |
157 | 160 | } |
158 | 161 | } |
159 | 162 | |
160 | 163 | // string test_uri = "rtmp://192.168.10.56:1935/objecteye/1"; |
161 | 164 | // string test_uri = "/home/cmhu/data/output_800x480.mp4"; |
162 | -string test_uri = "/home/cmhu/data/output_1920x1080.mp4"; | |
165 | +// string test_uri = "/home/cmhu/data/output_1920x1080.mp4"; | |
166 | +// string test_uri = "rtsp://176.10.0.2:8554/stream"; | |
167 | +string test_uri = "/home/cmhu/data2/Street.uvf"; | |
163 | 168 | |
164 | 169 | void createDecode(int index){ |
165 | 170 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
... | ... | @@ -226,24 +231,25 @@ int main(){ |
226 | 231 | |
227 | 232 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
228 | 233 | |
229 | - int count = 99; | |
230 | - for (size_t i = 0; i < count ; i++) | |
231 | - { | |
232 | - createDecode(i); | |
233 | - } | |
234 | + // int count = 99; | |
235 | + // for (size_t i = 0; i < count ; i++) | |
236 | + // { | |
237 | + // createDecode(i); | |
238 | + // } | |
234 | 239 | |
235 | 240 | MgrDecConfig config; |
236 | 241 | config.name = "dec"; |
237 | 242 | config.cfg.uri = test_uri; |
238 | 243 | config.cfg.post_decoded_cbk = postDecoded0; |
239 | 244 | config.cfg.force_tcp = true; |
240 | - config.cfg.gpuid = "1"; | |
245 | + config.cfg.gpuid = "2"; | |
241 | 246 | FFNvDecoder* dec2 = pDecManager->createDecoder(config); |
242 | 247 | if (!dec2) |
243 | 248 | { |
244 | 249 | return 1; |
245 | 250 | } |
246 | 251 | pDecManager->setUserPtr(config.name, dec2); |
252 | + pDecManager->setDecKeyframe(config.name, true); | |
247 | 253 | pDecManager->startDecodeByName(config.name); |
248 | 254 | |
249 | 255 | pthread_t m_decode_thread; |
... | ... | @@ -300,9 +306,9 @@ int main(){ |
300 | 306 | // // pDecManager->resumeDecoder("dec1"); |
301 | 307 | // pDecManager->resumeDecoder("dec2"); |
302 | 308 | |
303 | - cout << "总共帧数:" << sum << endl; | |
304 | - | |
305 | 309 | while (getchar() != 'q'); |
306 | 310 | |
311 | + cout << "总共帧数:" << sum << endl; | |
312 | + | |
307 | 313 | pDecManager->closeAllDecoder(); |
308 | 314 | } |
309 | 315 | \ No newline at end of file | ... | ... |