video analysis2.0拆分,ffmpeg封装go接口库
zhangmeng
2020-10-09 d64868c215e35088bfeda67aeb04db0800bf2844
h264 mp4
6个文件已修改
113 ■■■■ 已修改文件
csrc/common/gpu/info.cpp 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/common/gpu/info.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/ffmpeg/format/FormatIn.cpp 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/ffmpeg/format/FormatIn.hpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/ffmpeg/format/FormatOut.cpp 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/ffmpeg/format/FormatOut.hpp 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/common/gpu/info.cpp
@@ -412,6 +412,27 @@
    return -1;
}
bool satisfy(const int index, const int need, const int reserved){
    nvGpuInfo_t gpu_info;
    int ret = get_gpu_info(&gpu_info);
    if(!ret){
        if (gpu_info.device_count == 0) return -1;
        for(int i = 0; i < gpu_info.device_count; i++){
            if (i == index){
                int mem_free = (gpu_info.devices[i].memory_free >> 20) - reserved - need;
                if(mem_free > 0){
                    return true;
                }
            }
        }
    }
    return false;
}
int test(void)
{
    nvGpuInfo_t gpu_buf;
csrc/common/gpu/info.h
@@ -4,6 +4,7 @@
namespace gpu{
    int getGPU(const int need);
    int getGPUPrior(const int need, const int reserved, const int lastChoice);
    bool satisfy(const int index, const int need, const int reserved);
}
#endif
csrc/ffmpeg/format/FormatIn.cpp
@@ -2,6 +2,8 @@
#include <stdexcept>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
extern "C"{
#include <libavformat/avformat.h>
@@ -10,7 +12,7 @@
#include <libavutil/opt.h>
#include <libavutil/avassert.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <libswscale/swscale.h>
}
#include "../log/log.hpp"
@@ -69,7 +71,7 @@
            avformat_close_input(&ctx_);
            ctx_ = NULL;
        }
        if (handle_gb28181){
            delete handle_gb28181;
        }
@@ -95,7 +97,7 @@
            logIt("open with custom io create custom avio error\n");
            return -1;
        }
        ctx_ = avformat_alloc_context();
        if(!ctx_){
            logIt("open with custom io create format error\n");
@@ -147,7 +149,7 @@
        const int ret = avformat_open_input(&ctx_, filename, NULL, options);
        // if(ret < 0){
        //     logIt("open %s failed:%s",filename,
        //             getAVErrorDesc(ret).c_str());
        //             getAVErrorDesc(ret).c_str());
        // }
        return ret;
@@ -158,7 +160,7 @@
        const int ret = avformat_find_stream_info(ctx_, options);
        if(ret < 0){
            logIt("find %s stream info failed:%s",
                    ctx_->filename,getAVErrorDesc(ret).c_str());
                    ctx_->filename,getAVErrorDesc(ret).c_str());
            return false;
        }
@@ -178,7 +180,7 @@
                    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("in stream video fps %f, time_base: %d : %d, size: %dx%d", fps_, in->time_base.num, in->time_base.den, in->codecpar->width, in->codecpar->height);
            }
            if (type == AVMEDIA_TYPE_AUDIO){
@@ -198,6 +200,16 @@
        return ctx_->streams[vs_idx_]->codecpar->codec_id == AV_CODEC_ID_HEVC;
    }
    const bool FormatIn::isAVC1()const{
        if (IsHEVC()) return false;
        char p[100] = {0};
        char *sub = av_fourcc_make_string(p, ctx_->streams[vs_idx_]->codecpar->codec_tag);
        const int ret = strcmp(sub, "avc1");
        if (ret == 0) return true;
        return false;
    }
    bool FormatIn::openCodec(AVDictionary **options){
        if (vs_idx_ == -1) return false;
@@ -211,24 +223,42 @@
        int idle_gpu = -1;
        srand((unsigned)time(NULL));
constexpr int need = 350; // M
constexpr int reserved = 512; // M
        for (int i = 0; i < 2; ++i)
        {
            if(hw_accl_){
                idle_gpu = gpu::getGPUPrior(350, 896, 0);
                // idle_gpu = gpu::getGPU(300);
                // 设置gpu index
                if (prop_->gpu_index_ > -1){
                    if (!gpu::satisfy(prop_->gpu_index_, need, reserved)){
                        hw_accl_ = false;
                        continue;
                    }
                    idle_gpu = prop_->gpu_index_;
                }else{
                    idle_gpu = gpu::getGPUPrior(need, reserved, 0);
                    // idle_gpu = gpu::getGPU(300);
                    usleep(2000000 + rand()%3000000);
                    if (!gpu::satisfy(idle_gpu, need, reserved)){
                        hw_accl_ = false;
                        continue;
                    }
                }
                if(idle_gpu < 0){
                    logIt("NO GPU RESOURCE TO DECODE");
                    hw_accl_ = false;
                    continue;
                }
                std::string codec_name(avcodec_get_name(codecpar->codec_id));
                codec_name += "_cuvid";
                dec = avcodec_find_decoder_by_name(codec_name.c_str());
                if(!dec){
                    hw_accl_ = false;
                    continue;
@@ -257,7 +287,7 @@
                }
            }
        }
        return flag;
    }
csrc/ffmpeg/format/FormatIn.hpp
@@ -51,6 +51,7 @@
        AVFormatContext *getFromatContext(){return ctx_;}
        const double getFPS()const{return fps_;}
        const bool IsHEVC()const;
        const bool isAVC1()const;
    private:
         AVFormatContext     *ctx_;
         AVCodecContext         *dec_ctx_;
csrc/ffmpeg/format/FormatOut.cpp
@@ -33,11 +33,16 @@
    ,format_name_("mp4")
    ,in_v_stream_(NULL)
    ,in_a_stream_(NULL)
    ,bsf_h264(NULL)
    ,bsf_hevc(NULL)
    {}
    FormatOut::~FormatOut()
    {
        clear();
        if (bsf_h264) av_bsf_free(&bsf_h264);
        if (bsf_hevc) av_bsf_free(&bsf_hevc);
    }
    void FormatOut::clear(){
@@ -349,7 +354,23 @@
            flag = writeHeader(&avdic);
            av_dict_free(&avdic);
        }
        if (v){
            if (v->codecpar->codec_id == AV_CODEC_ID_H264){
                char p[100] = {0};
                char *sub = av_fourcc_make_string(p, v->codecpar->codec_tag);
                if (strcmp(sub, "avc1") == 0){
                    const AVBitStreamFilter *f = av_bsf_get_by_name("h264_mp4toannexb");
                    if (f){
                        if (av_bsf_alloc(f, &bsf_h264) >= 0){
                            if (avcodec_parameters_copy(bsf_h264->par_in, v->codecpar) >= 0){
                                if (av_bsf_init(bsf_h264) < 0) bsf_h264 = NULL;
                            }
                        }
                    }
                }
            }
        }
        return flag;
    }
    
@@ -456,6 +477,19 @@
    bool FormatOut::writeFrame2(AVPacket *pkt, bool interleaved){
        
        // h264_mp4toanatax
        if (bsf_h264){
            if (av_bsf_send_packet(bsf_h264, pkt) < 0){
                logIt("bsf_h264 send packet failed");
                return true;
            }
            if (av_bsf_receive_packet(bsf_h264, pkt) < 0){
                logIt("bsf_h264 recv packet failed");
                return true;
            }
        }
        //
        int ret = 0;
        if(interleaved){
            ret = av_interleaved_write_frame(ctx_, pkt);
csrc/ffmpeg/format/FormatOut.hpp
@@ -11,6 +11,7 @@
struct AVFrame;
struct AVPacket;
struct AVDictionary;
struct AVBSFContext;
namespace ffwrapper{
    class VideoProp;
@@ -72,6 +73,7 @@
        double                     fps_;
        std::string             format_name_;
        AVBSFContext               *bsf_h264, *bsf_hevc;
        // rec
        AVStream                  *in_v_stream_;
        AVStream                  *in_a_stream_;