Windows C++ 使用FFmpeg进行H264/H265编码调用流程介绍(有源码)

FFmpeg进行H264/H265编码网上代码还是比较多的,这边提供一下本人进行编码的代码(又不懂的可以私信我,相互交流)


    AVCodec *pCodec = NULL;//编码器        
    AVCodecContext *pCodecCtx;
    AVFrame *pFrame = NULL;
    AVPacket *pPkt = NULL;
    AVDictionary *dictParam = 0;
    do
    {
        pCodec = avcodec_find_encoder_by_name(编码器名称);//libx264 libx265 h264_amf h264_qsv h264_nvenc hevc_nvenc hevc_amf hevc_qsv
        if (!pCodec)
        {
            break;
        }

        pCodecCtx = avcodec_alloc_context3(pCodec);
        if (!pCodecCtx)
        {
            break;
        }
        
        pPkt = av_packet_alloc();
        if (!pPkt)
        {
            break;
        }

        pCodecCtx->width = w;
        pCodecCtx->height = h;
        pCodecCtx->time_base = { 1, 30 };
        pCodecCtx->framerate = { 30, 1 };
        pCodecCtx->gop_size =30;    //I帧间隔    
        pCodecCtx->max_b_frames = 0;
        pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
        pCodecCtx->thread_count = 1;
        pCodecCtx->refs = 1;//设置参考帧个数
        //这边不同的编码器的设置参数不一样,需要区别设置下,且每个人想要使用的方式也不一样,比如CQP,CBR,VBR,ABR,CRF等,大家根据自己的想法来
        av_dict_set(&dictParam, "tune", "zerolatency", 0);
        av_opt_set_int(pCodecCtx->priv_data, "qp", 17, 0);
        
        int ret = 0;
        try
        {
            ret = avcodec_open2(pCodecCtx, pCodec, &dictParam);
            if (ret < 0)
            {
                break;
            }
        }
        catch (...)
        {
            break;
        }

        pFrame = av_frame_alloc();
        if (!pFrame)
        {
            break;
        }

        pFrame->format = AV_PIX_FMT_YUV420P;
        pFrame->width = w;
        pFrame->height = h;
        if (pCodec->id == AV_CODEC_ID_H264) {
            ret = av_frame_get_buffer(pFrame, 8);
        }
        else if (pCodec->id == AV_CODEC_ID_H265 || pCodec->id == AV_CODEC_ID_HEVC) {
            ret = av_frame_get_buffer(pFrame, 32);
        }

        if (ret < 0)
        {
            break;
        }

        if (dictParam)
        {
            av_dict_free(&dictParam);
            dictParam = NULL;
        }
        bool bFirst = true;
        //开始编码
        while(1)
        {
            //传入一帧YUV420P数据
            memcpy(pFrame->data[0], Y数据, Y长度);
            memcpy(pFrame->data[1], U数据, U长度);
            memcpy(pFrame->data[2], V数据, V长度);
            
            if(bFirst)//首帧编译为I帧,其他P帧
            {
                pFrame->pict_type = AV_PICTURE_TYPE_I;
                pFrame->key_frame = 1;
                bFirst = false;
            }else{
                pFrame->pict_type = AV_PICTURE_TYPE_P;
                pFrame->key_frame = 0;
            }
            
            avcodec_send_frame(pCodecCtx,pFrame);
            
            while(1)
            {
                ret = avcodec_receive_packet(pCodecCtx, pPkt);//获取编码后的数据
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                {
                    break;
                }
                else if (ret < 0) {
                    av_packet_unref(pPkt);
                    break;
                }
                //编码成功
                av_packet_unref(pPkt);
            }
        }

    } while (false);
    if (dictParam)
    {
        av_dict_free(&dictParam);
        dictParam = NULL;
    }
  

     if (pCodecCtx) {
        avcodec_free_context(&pCodecCtx);
     }


    if (pPkt) {
        av_packet_free(&pPkt);
    }

    if (pFrame)
    {
        av_frame_free(&pFrame);
    }
    return 0;

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值