ffmpeg对接darknet优化

该博客详细介绍了如何使用ffmpeg对接darknet进行视频流处理优化,包括连接设置、解码过程、图像格式转换,并展示了对接YOLO模型进行目标检测的实现。涉及关键步骤如avformat_open_input、avcodec_open2、图像数据转换等,以及优化操作,如选择合适的图像格式和大小以提高效率。
摘要由CSDN通过智能技术生成

#include "H264DecoderThread.h"
#include "Poco/Thread.h"  
#include<iostream>
#include<fstream>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>

using namespace std;
using Poco::Thread;

FFmpegErrorCode H264DecoderThread::connect()
{
    AVDictionary *opts = 0;
    av_dict_set(&opts, "rtsp_transport", "tcp", 0);
    av_dict_set(&opts, "stimeout", "1000000", 0);
    FFmpegErrorCode res = FFmpeg_NoError;

    printf("H264DecoderThread connect()\n");

    do 
    {
        if (avformat_open_input(&m_pFormatCtx, m_strMrl.c_str(), NULL, &opts) != 0)
        {
            res = FFmpeg_ConnectFail;
            break;
        }

        if (avformat_find_stream_info(m_pFormatCtx, NULL) < 0)
        {
            res = FFmpeg_FindStreamInfo;
            break;
        }

        m_nVideoStreamIndex = av_find_best_stream(m_pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
        if (m_nVideoStreamIndex < 0)
        {
            res = FFmpeg_FindBestStream;
            break;
        }
        AVStream* st = m_pFormatCtx->streams[m_nVideoStreamIndex];
        AVCodec *pCodec = avcodec_find_decoder(st->codec->codec_id);
        if (!pCodec || avcodec_open2(st->codec, pCodec, NULL) < 0)
        {
            res = FFmpeg_FindDecoder;
            break;
        }
    } while (false);
    if (res != FFmpeg_NoError)
    {
        avformat_close_input(&m_pFormatCtx);
    }
    else
    {
        m_bConnected = true;

        string names_file = "coco.names";
        string cfg_file = "yolov3.cfg";
        string weights_file = "yolov3.weights";

       pDetector = new Detector(cfg_file, weights_file);
        
        if (pDetector == NULL) 
        {
            printf("error pDetector == NULL\n");
        }

        #if 0
        m_dst_pix_fmt = AV_PIX_FMT_RGB24;
        m_dst_w = 1280;
        m_dst_h = 720;
        m_dst_c = 3;
        #else
        m_dst_pix_fmt = AV_PIX_FMT_BGR24;
        m_dst_w = 416;
        m_dst_h = 416;
        m_dst_c = 3;
        #endif
        
    }
    av_dict_free(&opts);
    return res;
}

void H264DecoderThread::AddTask(PicInfo &picInfo)
{
    
    printf("H264DecoderThread AddTask()\n");
}

//点符号初始化方式
//       注意在此方式在,和C
//风格不同,成员初始化不可以乱序初始化,否则编辑器将给出错误:“对不起,尚未实现:不平凡的代理初始值设定不受支持”。

/*
typedef struct AVPixFmtDescriptor {
    const char *name;
    uint8_t nb_components;  ///< The number of components each pixel has, (1-4)
    uint8_t log2_chroma_w;
    uint8_t log2_chroma_h;
    uint64_t flags;
    AVComponentDescriptor comp[4];
    const char *alias;
} AVPixFmtDescriptor;

注意: c++ 初始化 , 数组必须按以下枚举顺序, 且结构体内部按顺序
enum AVPixelFormat {
    AV_PIX_FMT_NONE = -1,
    AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
    AV_PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
    AV_PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
    AV_PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
    AV_PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
    AV_PIX_FMT_YUV444P, 

*/
static const AVPixFmtDescriptor my_av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
    [AV_PIX_FMT_YUV420P] = {
        .name = "yuv420p",
        .nb_components = 3,
        .log2_chroma_w = 1,
        .log2_chroma_h = 1,
        .flags = AV_PIX_FMT_FLAG_PLANAR,
        .comp = {
            { 0, 1, 0, 0, 8, 0, 7, 1 },        /* Y */
            { 1, 1, 0, 0, 8, 0, 7, 1 },        /* U */
            { 2, 1, 0, 0, 8, 0, 7, 1 },        /* V */
        },
        .alias = 0,

    },

    [AV_PIX_FMT_YUYV422] = {
        .name = "yuyv422",
        .nb_components = 3,
        .log2_chroma_w = 1,
        .log2_chroma_h = 0,
        .flags = 0,
        .comp = {
            { 0, 2, 0, 0, 8, 1, 7, 1 },        /* Y */
            { 0, 4, 1, 0, 8, 3, 7, 2 },        /* U */
            { 0, 4, 3, 0, 8, 3, 7, 4 },        /* V */
        },
        .alias = 0,
    },

    [AV_PIX_FMT_RGB24] = {
        .name = "rgb24",
        .nb_components = 3,
        .log2_chroma_w = 0,
        .log2_chroma_h = 0,
         .flags = AV_PIX_FMT_FLAG_RGB,
        .comp = {
            { 0, 3, 0, 0, 8, 2, 7, 1 },        /* R */
            { 0, 3, 1, 0, 8, 2, 7, 2 },        /* G */
            { 0, 3, 2, 0, 8, 2, 7, 3 },        /* B */
        },
       .alias = 0,
    },
    [AV_PIX_FMT_BGR24] = {
        .name = "bgr24",
        .nb_components = 3,
        .log2_chroma_w = 0,
        .log2_chroma_h = 0,
        .flags = AV_PIX_FMT_FLAG_RGB,
        .comp = {
            { 0, 3, 2, 0, 8, 2, 7, 3 },        /* R */
            { 0, 3, 1, 0, 8, 2, 7, 2 },        /* G */
            { 0, 3, 0, 0, 8, 2, 7, 1 },        /* B */
        },
        .alias = 0,
    },

};


static inline
int my_image_get_linesize(int width, int plane,
                       int max_step, int max_step_comp,
                       const AVPixFmtDescriptor *desc)
{
    int s, shifted_w, linesize;

    if (!desc)
        return AVERROR(EINVAL);

    if (width < 0)
        return AVERROR(EINVAL);
    s = (max_step_comp == 1 || max_step_comp == 2) ? desc->log2_chroma_w : 0;
    shifted_w = ((width + (1 << s) - 1)) >> s;
    if (shifted_w && max_step > INT_MAX / shifted_w)
        return AVERROR(EINVAL);
    linesize = max_step * shifted_w;

    if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
        linesize = (linesize + 7) >> 3;
    return linesize;
}

const AVPixFmtDescriptor *my_av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
{
    printf("A my_av_pix_fmt_desc_get pix_fmt %d \n", pix_fmt);
    if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
        return NULL;

    
    printf("B my_av_pix_fmt_desc_get pix_fmt %d \n", pix_fmt);
    return &my_av_pix_fmt_descriptors[pix_fmt];
}


int my_av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
{
    int i, ret;
    const AVPixFmtDescriptor *desc =

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值