video analysis2.0拆分,ffmpeg封装go接口库
zhangmeng
2019-09-20 be9c1d1f659b0ff31f656424c478e83a4f7c53b5
csrc/ffmpeg/format/FormatIn.cpp
@@ -29,17 +29,24 @@
   :ctx_(NULL)
   ,dec_ctx_(NULL)
   ,vs_idx_(-1)
   ,as_idx_(-1)
   ,hw_accl_(hw)
   ,io_ctx_(NULL)
   ,read_io_buff_(NULL)
   ,read_io_buff_size_(32768)
   ,handle_gb28181(NULL)
   ,fps_(25.0)
   {}
   FormatIn::~FormatIn()
   {
      if(io_ctx_){
         free(read_io_buff_);
         avio_close(io_ctx_);
         if(read_io_buff_){
            // av_free(read_io_buff_);
            read_io_buff_ = NULL;
         }
         avio_context_free(&io_ctx_);
         io_ctx_ = NULL;
      }
      if(ctx_){
         avformat_close_input(&ctx_);
@@ -47,12 +54,16 @@
         ctx_ = NULL;
         if(dec_ctx_){
            avcodec_close(dec_ctx_);
            dec_ctx_ = NULL;
         }
      }
      if (handle_gb28181){
         delete handle_gb28181;
      }
   }
////////////////////////////////////////////////////////////////////////
   int FormatIn::openWithCustomIO(read_packet fn, AVDictionary **options/*=NULL*/){
   int FormatIn::openWithCustomIO(void *opaque, read_packet fn, AVDictionary **options/*=NULL*/){
      ctx_ = avformat_alloc_context();
      if(!ctx_){
         logIt("open with custom io create format error");
@@ -64,30 +75,55 @@
         return -1;
      }
      io_ctx_ = avio_alloc_context(read_io_buff_, read_io_buff_size_, 0, NULL, fn, NULL, NULL);
      io_ctx_ = avio_alloc_context(read_io_buff_, read_io_buff_size_, 0, opaque, fn, NULL, NULL);//opaque
      if(!io_ctx_){
         logIt("open with custom io create custom avio error");
         return -1;
      }
      ctx_->pb = io_ctx_;
      auto err = av_probe_input_buffer(io_ctx_, &ctx_->iformat, NULL, NULL, 0, read_io_buff_size_);
      auto err = av_probe_input_buffer(ctx_->pb, &ctx_->iformat, NULL, NULL, 0, read_io_buff_size_);
      if(err != 0){
         logIt("open with custom io prob input buffer error");
         logIt("open with custom io prob input buffer error:%d", err);
            logIt("failed:%s", getAVErrorDesc(err).c_str());
         return -1;
      }
      return 0;
   }
   int FormatIn::openGb28181(const char *filename, AVDictionary **options){
       std::string fn = filename;
      //GB28181API gb28181(fn);
      if (handle_gb28181){
         delete handle_gb28181;
      }
      handle_gb28181 = new GB28181API;
      handle_gb28181->addCamera(fn);
        int ret = openWithCustomIO(handle_gb28181, handle_gb28181->readData, options);
        if(ret < 0){
            logIt("do openWithCustomIO failed:%d",ret);
        }
        ret = avformat_open_input(&ctx_, "", NULL, options);
        // if(ret < 0){
            // logIt("open %s failed:%s",filename,
            //       getAVErrorDesc(ret).c_str());
        // }
      return ret;
   }
/////////////////////////////////////////////////////////////////////////
   int FormatIn::open(const char *filename, AVDictionary **options){
      const int ret = avformat_open_input(&ctx_, filename, NULL, options);
      if(ret < 0){
         logIt("open %s failed:%s",filename,
               getAVErrorDesc(ret).c_str());
      }
      // if(ret < 0){
      //    logIt("open %s failed:%s",filename,
      //          getAVErrorDesc(ret).c_str());
      // }
      return ret;
   }
@@ -102,15 +138,25 @@
         return false;
      }
      logIt("there are %d stream", ctx_->nb_streams);
      for (int i = 0; i < ctx_->nb_streams; ++i)
      {
         switch(ctx_->streams[i]->codecpar->codec_type){
            case AVMEDIA_TYPE_VIDEO:
               vs_idx_ = i;
               break;
         auto type = ctx_->streams[i]->codecpar->codec_type;
         if (type == AVMEDIA_TYPE_VIDEO){
            vs_idx_ = i;
            default:
               break;
            auto in = ctx_->streams[i];
            if(in->r_frame_rate.num >=1 && in->r_frame_rate.den >= 1){
                   fps_ = av_q2d(in->r_frame_rate);
               }else if(in->avg_frame_rate.num >=1 && in->avg_frame_rate.den >= 1){
                   fps_ = av_q2d(in->avg_frame_rate);
               }
            logIt("video stream time base %d : %d", in->time_base.num, in->time_base.den);
         }
         if (type == AVMEDIA_TYPE_AUDIO){
            as_idx_ = i;
            logIt("audio stream time base %d : %d", ctx_->streams[i]->time_base.num, ctx_->streams[i]->time_base.den);
         }
      }
      return true;
@@ -216,43 +262,52 @@
      return true;
   }
   AVStream *FormatIn::getStream(int type){
      return ctx_->streams[vs_idx_];
   AVStream *FormatIn::getStream(int type/*=-1*/){
      if (type == -1){
         return ctx_->streams[vs_idx_];
      }
      if (type == ctx_->streams[vs_idx_]->codecpar->codec_type)
         return ctx_->streams[vs_idx_];
      if (type == ctx_->streams[as_idx_]->codecpar->codec_type)
         return ctx_->streams[as_idx_];
      return NULL;
   }
   AVCodecContext *FormatIn::getCodecContext(int type){
      return dec_ctx_;
   }
   
   bool FormatIn::readPacket(AVPacket &pkt_out, int stream_index){
      bool founded = false;
      while (!founded){
         const int ret = av_read_frame(ctx_, &pkt_out);
         if(ret < 0){
            logIt("read frame from %s failed:%s",
                  ctx_->filename,getAVErrorDesc(ret).c_str());
            return false;
         }
         if(pkt_out.stream_index == stream_index){
            founded = true;
         }else{
            av_free_packet(&pkt_out);
            av_init_packet(&pkt_out);
            pkt_out.data = NULL;
            pkt_out.size = 0;
         }
   bool FormatIn::isVideoPkt(AVPacket &pkt){
      if (pkt.stream_index == vs_idx_){
         return true;
      }
      pkt_out.stream_index = 0;
      return false;
   }
   bool FormatIn::isAudioPkt(AVPacket &pkt){
      if (pkt.stream_index == as_idx_){
         return true;
      }
      return false;
   }
   bool FormatIn::readPacket(AVPacket &pkt_out){
      const int ret = av_read_frame(ctx_, &pkt_out);
      if(ret < 0){
         return false;
      }
      return true;
   }
   bool FormatIn::readPacket(std::shared_ptr<CodedData> &data, int stream_index){
   bool FormatIn::readPacket(std::shared_ptr<CodedData> &data){
      AVPacket &pkt(data->getAVPacket());
      return readPacket(pkt, getStream()->index);
      return readPacket(pkt);
   }
   int FormatIn::decode(AVFrame* &frame, AVPacket &pkt){