Commit c2ff6d2adf6c4cf758483285e17ebaf5bcefb97b

Authored by Hu Chunming
1 parent c027963f

初步实现ffmepg接收rtp流

src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -174,7 +174,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
174 174 }
175 175  
176 176 // 查找视频流信息
177   - const AVCodec *decoder = nullptr;
  177 + AVCodec *decoder = nullptr;
178 178 video_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
179 179 if (video_index < 0) {
180 180 LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name);
... ...
src/decoder/dvpp/DvppRtpDecoder.cpp
... ... @@ -224,13 +224,13 @@ bool DvppRtpDecoder::isSurport(FFDecConfig&amp; cfg){
224 224 }
225 225  
226 226 bool DvppRtpDecoder::start(){
  227 +
  228 + m_bRunning = true;
227 229  
228 230 if(!probe()) {
229 231 return false;
230 232 }
231 233  
232   - m_bRunning = true;
233   -
234 234 m_read_thread = new std::thread([](void* arg)
235 235 {
236 236 DvppRtpDecoder* a=(DvppRtpDecoder*)arg;
... ... @@ -362,62 +362,82 @@ void DvppRtpDecoder::release_ffmpeg() {
362 362  
363 363 void DvppRtpDecoder::CacheBuffer(uint8_t* recvBuf, int recvBufSize) {
364 364 if ((m_bufferSize + recvBufSize - RTP_HEADER_SIZE) < MAX_RTP_BUFFER_SIZE) {
365   - memcpy(m_buffer + m_bufferSize, recvBuf + RTP_HEADER_SIZE, recvBufSize - RTP_HEADER_SIZE);
366   - m_bufferSize += recvBufSize - RTP_HEADER_SIZE;
367   - } else {
  365 + memcpy(m_buffer + m_bufferSize, recvBuf + RTP_HEADER_SIZE, recvBufSize - RTP_HEADER_SIZE);
  366 + m_bufferSize += recvBufSize - RTP_HEADER_SIZE;
  367 + } else {
368 368 LOG_WARN("recvBufSize = {} over MAX_RTP_BUFFER_SIZE ", recvBufSize);
369 369 }
370 370 }
371 371  
372 372 int DvppRtpDecoder::ReadBuffer(uint8_t* buf, int buffsize) {
373 373 int ret = 0;
  374 + int count = 0;
  375 + while(m_bRunning && (m_bufferSize < 4096 || m_bufferSize < buffsize)){
  376 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  377 + count++;
  378 + if (count >= 1000) {
  379 + // 只等待10s
  380 + return -1;
  381 + }
  382 + }
  383 +
374 384 if (m_bufferSize >= buffsize) {
375 385 memcpy(buf, m_buffer, buffsize);
376 386 m_bufferSize = m_bufferSize - buffsize;
377 387 memmove(m_buffer, m_buffer + buffsize, m_bufferSize);
378 388 ret = buffsize;
379   -
380   - LOG_DEBUG("avio_read_packet={}", buffsize);
381 389 }
382 390  
  391 + printf("m_bufferSize=%d buffsize=%d\n", m_bufferSize.load(), buffsize);
  392 +
383 393 return ret;
384 394 }
385 395  
386 396 bool DvppRtpDecoder::probe() {
  397 +
387 398 // todo: 此处可能有泄露
388   - unsigned char* avioBuff = (unsigned char*)av_malloc(7680 * 4320);
389   - ioCtx = avio_alloc_context(avioBuff, sizeof(avioBuff), 0, this, avio_read_packet, NULL, NULL);
  399 + unsigned char* avioBuff = (unsigned char*)av_malloc(MAX_RTP_BUFFER_SIZE);
  400 + AVIOContext *ioCtx = avio_alloc_context(avioBuff, sizeof(avioBuff), 0, this, avio_read_packet, NULL, NULL);
390 401 //探测流(获取码流格式)
391   - const AVInputFormat* inputFmt;
392   - int ret = av_probe_input_buffer2(ioCtx, &inputFmt, "", NULL, 0, 0);
  402 + AVInputFormat* inputFmt = nullptr;
  403 + int ret = av_probe_input_buffer(ioCtx, &inputFmt, "", NULL, 0, 0);
393 404 if (ret < 0){
394   - LOG_ERROR("av_probe_input_buffer2 error: {}", ret);
  405 + LOG_ERROR("av_probe_input_buffer error: {}", ret);
395 406 return false;
396 407 }
397 408  
398 409 do{
399 410 fmt_ctx = avformat_alloc_context();
  411 +
  412 + fmt_ctx->probesize = 10000000;//5 000 000
  413 + fmt_ctx->flags |= AVFMT_FLAG_NOBUFFER;
  414 + av_opt_set(fmt_ctx->priv_data,"preset","ultrafast",0);
  415 +
  416 + //AV_TIME_BASE = 1000 000
  417 + fmt_ctx->max_analyze_duration = 90 * AV_TIME_BASE;
  418 +
400 419 fmt_ctx->pb = ioCtx;
401 420  
402 421  
403 422 AVDictionary* net_options{nullptr};//网络连接参数
404   -
405   - //配置流参数
406   - //av_dict_set(&net_options, "fflags", "nobuffer", 0); //不缓存直接解码
  423 + // av_dict_set(&net_options, "fflags", "nobuffer", 0); //不缓存直接解码
  424 + av_dict_set( &net_options, "bufsize", "655360", 0 );
  425 + av_dict_set( &net_options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
  426 + av_dict_set( &net_options, "max_delay", "500000", 0); //设置最大时延
407 427  
408 428 //打开流
409   - ret = avformat_open_input(&fmt_ctx, "", inputFmt, &net_options);
410   - if (ret != 0)
411   - {
  429 + ret = avformat_open_input(&fmt_ctx, 0, 0, &net_options);
  430 + if (ret != 0) {
412 431 LOG_ERROR("avformat_open_input error: {}", ret);
413 432 break;
414 433 }
  434 +
415 435 //获取流信息
416   - if (avformat_find_stream_info(fmt_ctx, NULL) < 0)//?
417   - {
  436 + if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
418 437 LOG_ERROR("avformat_find_stream_info error");
419 438 break;
420 439 }
  440 +
421 441 //获取视频流
422 442 mVideoIndex = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
423 443 if (mVideoIndex < 0)
... ... @@ -550,8 +570,8 @@ void DvppRtpDecoder::read_thread() {
550 570 if (result == AVERROR_EOF || result < 0){
551 571 av_packet_free(&pkt);
552 572 pkt = nullptr;
553   - LOG_WARN("[{}]- Failed to read frame!", m_dec_name);
554   - break;
  573 + // LOG_WARN("[{}]- Failed to read frame!", m_dec_name);
  574 + continue;
555 575 }
556 576  
557 577 if (m_DvppCacheCounter.load() > m_cache_gop){
... ...
src/decoder/dvpp/DvppRtpDecoder.h
... ... @@ -106,7 +106,6 @@ private:
106 106  
107 107 // 读取数据
108 108 AVFormatContext *fmt_ctx{nullptr};
109   - AVIOContext * ioCtx{nullptr};
110 109 int mVideoIndex {-1};
111 110 AVPixelFormat pix_fmt;
112 111 AVCodecContext *avctx{nullptr};
... ...
src/decoder/gb28181/rtp2/RTPReceiver2.cpp
... ... @@ -184,7 +184,7 @@ int RTPReceiver2::tcp_server() {
184 184 char buff[4096];
185 185 int n;
186 186  
187   - if( (listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ){
  187 + if( (listenfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)) == -1 ){
188 188 printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
189 189 return 0;
190 190 }
... ... @@ -204,23 +204,30 @@ int RTPReceiver2::tcp_server() {
204 204 return 0;
205 205 }
206 206  
207   - char recvBuf[10000];
  207 + uint8_t recvBuf[10000];
208 208 int recvBufSize = 0;
209 209  
  210 + bool bFilter = false;
  211 +
210 212 while (!m_bRtpExit)
211 213 {
212   - LOG_INFO("阻塞监听新连接...");
  214 + // LOG_INFO("阻塞监听新连接...");
213 215 // 阻塞接收请求 start
214 216 socklen_t len = sizeof(sockaddr);
215 217 sockaddr_in accept_addr;
216 218 int clientFd = accept(listenfd, (struct sockaddr*)&accept_addr, &len);
217 219 if (clientFd < 0) {
218   - LOG_WARN("accept connection error");
  220 + if (!bFilter) {
  221 + LOG_WARN("accept connection warn");
  222 + bFilter = true;
  223 + }
  224 +
219 225 std::this_thread::sleep_for(std::chrono::milliseconds(5));
220 226 continue;
221 227 }
222 228 // 阻塞接收请求 end
223 229 LOG_INFO("发现新连接:clientFd={}", clientFd);
  230 + bFilter = false;
224 231  
225 232 while (!m_bRtpExit) {
226 233 recvBufSize = recv(clientFd, recvBuf, sizeof(recvBuf), 0);
... ... @@ -244,7 +251,7 @@ int RTPReceiver2::tcp_server() {
244 251 return 0;
245 252 }
246 253  
247   -void RTPReceiver2::parseTcpData(char* recvBuf, int recvBufSize) {
  254 +void RTPReceiver2::parseTcpData(uint8_t* recvBuf, int recvBufSize) {
248 255  
249 256 if ((mRecvCacheSize + recvBufSize) > Server_cache_max_size) {
250 257 LOG_ERROR("超过缓冲容量上限,忽略本次读取的数据。mRecvCacheSize=%d,recvBufSize=%d",mRecvCacheSize, recvBufSize);
... ... @@ -277,10 +284,10 @@ void RTPReceiver2::parseTcpData(char* recvBuf, int recvBufSize) {
277 284  
278 285 struct RtpHeader rtpHeader;
279 286 parseRtpHeader(mRecvRtpBuffer, &rtpHeader);
280   - printf("get a rtp seq=%d,RtpBufferSize=%d,mRecvCacheSize=%d,marker=%d,timestamp=%d\n",
281   - rtpHeader.seq,
282   - mRecvRtpBufferSize,
283   - mRecvCacheSize,rtpHeader.marker, rtpHeader.timestamp);
  287 + // printf("get a rtp seq=%d,RtpBufferSize=%d,mRecvCacheSize=%d,marker=%d,timestamp=%d\n",
  288 + // rtpHeader.seq,
  289 + // mRecvRtpBufferSize,
  290 + // mRecvCacheSize,rtpHeader.marker, rtpHeader.timestamp);
284 291  
285 292 // buffer 抛出
286 293 m_buffer_cbk(m_bufferParam, mRecvRtpBuffer, mRecvRtpBufferSize, rtpHeader.timestamp);
... ...
src/decoder/gb28181/rtp2/RTPReceiver2.h
... ... @@ -36,7 +36,7 @@ public:
36 36  
37 37 private:
38 38 bool start_server(string channel_id, int port, bool isUdp);
39   - void parseTcpData(char* recvBuf, int recvBufSize);
  39 + void parseTcpData(uint8_t* recvBuf, int recvBufSize);
40 40  
41 41 public:
42 42 uint8_t* mRecvCache {nullptr};
... ...