C++调用ffmpeg sdk开发

刚入职编解码开发岗,之前做的都是算法设计,没有接触过sdk开发。

开始用博客来记录自己的学习过程吧,希望有一天自己也可以成为大佬。

调用ffmpeg sdk来实现mp4格式到avi格式的转换

...本来想通过实现各个格式的相互转换来熟悉ffmpeg的,但是发现内容有点多,就只实现了mp4转成avi格式。

1.ffmpeg库编译

①直接从官网下载已经编译好的ffmpeg,这个网上很多介绍的文章

大佬的博客:【精选】Windows编译和使用ffmpeg_windows ffmpeg_心愿许得无限大的博客-CSDN博客

②自己动手,编译源码得到自己想要的库。在linux下比较简单,编译三步曲就OK了。

./configure 

make

make install

windows下面得下载MINGW来编译,听说是专门用来编译ffmpeg的,确实不错。

编译完以后就可以得到这样一个文件夹了,想要的东西里面都有

2.c++调用ffmpeg的库

用我们宇宙最强IDE VS来创建C++项目,整个空项目就行

配置一下项目链接器里的常规和输入两个地方把咱们的ffmpeg库给它配进去

常规->附加库目录:把lib库的路径加进去

输入->附加依赖项:把需要用到的dll.a库全部写进去

3.编写格式转换代码

环境没问题了就开始写我们的格式转换吧。首先整体的流程,在网上看到有大佬给出了基于ffmpeg格式转换的流程,如下图,是FLV转到AVI的,我只有几个MP4文件,所以就参考大佬的流程做一个MP4转AVI吧。

总体来说流程还不是太难

①解封装,包括了视频和音频,两个咱们分开处理

②解码,用输入文件对应的解码器将音视频码流解码成普通数据(YUV、PCM等等)

③编码,我们想要输出的格式对应的编码器将数据再编码成码流

④再封装,装好就可以输出了,得到我们想要的格式了。

在网上也看到有大佬总结了各种音视频封装格式可以使用的编解码器,如下图

下面直接给上代码,每一步都有相应的注释

/*
* @Time: 2023.10.24
* @Author: Wu Liu
* @File: T_format6.cpp
* @Function: format conversion
*/
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>

}
#include <iostream>
/* @T_format6.cpp
* 基本流程:
* 1.解析输入文件,获得流信息,确定音视频解码器参数、上下文。
* 2.根据输出要求配置音视频编码器参数
* 3.循环每一帧解码、再编码输出
* 4.内存清理
*/
bool Format_conver(const std::string& inputFile, const std::string& outputFileName, const std::string& Format) {
    avformat_network_init(); // 初始化网络库
    AVFormatContext* inputFormatContext = nullptr;
    AVCodecContext* videoCodecContext = nullptr;
    AVCodecContext* audioCodecContext = nullptr;
    AVFormatContext* outputFormatContext = nullptr;
    AVStream* videoStream = nullptr;
    AVStream* audioStream = nullptr;
    SwsContext* swsContext = nullptr;
    AVCodecID videoCodecId ;
    AVCodecID audioCodecId ;

    if (Format == "avi") 
    {
       videoCodecId = AV_CODEC_ID_MPEG2VIDEO;
       audioCodecId = AV_CODEC_ID_PCM_S16LE;
    }
    else if (Format == "mp4")
    {
        videoCodecId = AV_CODEC_ID_H264;
        audioCodecId = AV_CODEC_ID_AAC;
    }
    else if (Format == "wmv")
    {
       videoCodecId = AV_CODEC_ID_MSMPEG4V3;
       audioCodecId = AV_CODEC_ID_WMAV2;
    }
    else if (Format == "mkv")
    {
        videoCodecId = AV_CODEC_ID_H264;
        audioCodecId = AV_CODEC_ID_MP3;
    }
    else if (Format == "flv")
    {
        videoCodecId = AV_CODEC_ID_MPEG4;
        audioCodecId = AV_CODEC_ID_AAC;
    }
    else {
        std::cout << "不支持转换为这种格式" << std::endl;
        return false;
    }
    

    // 打开输入文件
    if (avformat_open_input(&inputFormatContext, inputFile.c_str(), nullptr, nullptr) != 0) {
        std::cout << "无法打开输入文件" << std::endl;
        return false;
    }

    // 获取流信息
    if (avformat_find_stream_info(inputFormatContext, nullptr) < 0) {
        std::cout << "无法获取输入文件流信息" << std::endl;
        avformat_close_input(&inputFormatContext);
        return false;
    }

    // 查找视频流和音频流索引
    int videoStreamIndex = -1;
    int audioStreamIndex = -1;
    for (int i = 0; i < inputFormatContext->nb_streams; i++) {
        if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
        }
        else if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audioStreamIndex = i;
        }
    }

    if (videoStreamIndex == -1 || audioStreamIndex == -1) {
        std::cout << "没有找到视频流" << std::endl;
        avformat_close_input(&inputFormatContext);
        return false;
    }

    // 获取视频和音频流
    videoStream = inputFormatContext->streams[videoStreamIndex];
    audioStream = inputFormatContext->streams[audioStreamIndex];

    // 获取视频解码器
    const AVCodec* videoCodec = avcodec_find_decoder(videoStream->codecpar->codec_id);
    if (!videoCodec) {
        std::cout << "没有找到视频解码器" << std::endl;
        avformat_close_input(&inputFormatContext);
        return false;
    }

    // 创建并打开视频解码器上下文
    videoCodecContext = avcodec_alloc_context3(videoCodec);
    if (!videoCodecContext) {
        std::cout << "创建视频解码器上下文失败"<< std::endl;
        avformat_close_input(&inputFormatContext);
        return false;
    }
    //视频流参数去填充上下文context
    avcodec_parameters_to_context(videoCodecContext, videoStream->codecpar);
    if (avcodec_open2(videoCodecContext, videoCodec, nullptr) < 0) {
        std::cout << "打开视频解码器失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        return false;
    }

    // 获取音频编码器
    const AVCodec* audioCodec = avcodec_find_decoder(audioStream->codecpar->codec_id);
    if (!audioCodec) {
        std::cout << "获取音频编码器失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        return false;
    }

    // 创建并打开音频解码器上下文
    audioCodecContext = avcodec_alloc_context3(audioCodec);
    if (!audioCodecContext) {
        std::cout << "创建音频编码器上下文失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        return false;
    }
    //音频流参数填充上下文
    avcodec_parameters_to_context(audioCodecContext, audioStream->codecpar);
    if (avcodec_open2(audioCodecContext, audioCodec, nullptr) < 0) {
        std::cout << "打开音频编码器失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        return false;
    }

    // 创建输出文件的上下文
    avformat_alloc_output_context2(&outputFormatContext, nullptr, nullptr, outputFileName.c_str());
    if (!outputFormatContext) {
        std::cout << "创建输出文件的上下文失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        return false;
    }

    // 添加视频流到输出上下文
    AVStream* outVideoStream = avformat_new_stream(outputFormatContext, nullptr);
    if (!outVideoStream) {
        std::cout << "添加视频流到输出文件失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext); 
        avformat_free_context(outputFormatContext);
        return false;
    }
    outVideoStream->id = outputFormatContext->nb_streams - 1;
 //   avcodec_parameters_copy(outVideoStream->codecpar, videoStream->codecpar);
    outVideoStream->codecpar->codec_tag = 0;

    // 设置视频编码器
    const AVCodec* outVideoCodec = avcodec_find_encoder(videoCodecId);
    if (!outVideoCodec) {
        std::cout << "设置视频编码器失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        return false;
    }
    AVCodecContext* outVideoCodecContext = avcodec_alloc_context3(outVideoCodec);
    if (!outVideoCodecContext) {
        std::cout << "设置视频编码器上下文失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        return false;
    }
    //视频编码器参数设置
    //avcodec_parameters_to_context(outVideoCodecContext, outVideoStream->codecpar);
    outVideoCodecContext->codec_id = videoCodecId;
    //outVideoCodecContext->time_base = videoStream->time_base;
    outVideoCodecContext->time_base.den = 25;
    outVideoCodecContext->time_base.num = 1;
    outVideoCodecContext->gop_size = 13;
    outVideoCodecContext->bit_rate = 8000000;
    outVideoCodecContext->refs = 0;
    outVideoCodecContext->max_b_frames = 4;
    outVideoCodecContext->width = 1920;
    outVideoCodecContext->height = 1080;
    outVideoCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
    
    //从输出上下文中复制参数到输出流
    avcodec_parameters_from_context(outVideoStream->codecpar, outVideoCodecContext);    
    // 打开视频编码器
    if (avcodec_open2(outVideoCodecContext, outVideoCodec, nullptr) < 0) {
        std::cout << "无法打开视频编码器" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        return false;
    }

    // 添加音频流到输出文件
    AVStream* outAudioStream = avformat_new_stream(outputFormatContext, nullptr);
    if (!outAudioStream) {
        std::cout << "添加音频流到输出文件失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        return false;
    }
    outAudioStream->id = outputFormatContext->nb_streams - 1;
    //输出音频流参数复制
    avcodec_parameters_copy(outAudioStream->codecpar, audioStream->codecpar);
    outAudioStream->codecpar->codec_tag = 0;

    // 设置音频编码器
    const AVCodec* outAudioCodec = avcodec_find_encoder(audioCodecId);
    if (!outAudioCodec) {
        std::cout << "设置音频编码器失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        return false;
    }
    AVCodecContext* outAudioCodecContext = avcodec_alloc_context3(outAudioCodec);
    if (!outAudioCodecContext) {
        std::cout << "设置音频编码器上下文失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        return false;
    }
    //音频编码器参数
    avcodec_parameters_to_context(outAudioCodecContext, outAudioStream->codecpar);
    outAudioCodecContext->codec_id = audioCodecId;
    outAudioCodecContext->time_base = audioStream->time_base;
    outAudioCodecContext->sample_fmt = AV_SAMPLE_FMT_S16;
    avcodec_parameters_from_context(outAudioStream->codecpar, outAudioCodecContext);

    // 打开音频编码器
    if (avcodec_open2(outAudioCodecContext, outAudioCodec, nullptr) < 0) {
        std::cout << "无法打开音频编码器" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        avcodec_free_context(&outAudioCodecContext);
        return false;
    }

    // 打开输出文件
    if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)) {
        if (avio_open(&outputFormatContext->pb, outputFileName.c_str(), AVIO_FLAG_WRITE) < 0) {
            std::cout << "无法打开输出文件" << std::endl;
            avformat_close_input(&inputFormatContext);
            avcodec_free_context(&videoCodecContext);
            avcodec_free_context(&audioCodecContext);
            avformat_free_context(outputFormatContext);
            avcodec_free_context(&outVideoCodecContext);
            avcodec_free_context(&outAudioCodecContext);
            return false;
        }
    }

    // 写入输出文件头
    if (avformat_write_header(outputFormatContext, nullptr) < 0) {
        std::cout << "无法写入输出文件头" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        avcodec_free_context(&outAudioCodecContext);
        return false;
    }
    //打印输出相关信息
    av_dump_format(outputFormatContext, 0, outputFileName.c_str(), 1);
    // 分配帧对象
    AVFrame* videoFrame = av_frame_alloc();
    AVFrame* audioFrame = av_frame_alloc();
    AVPacket* inputPacket = av_packet_alloc();
    AVPacket* videoOutputPacket = av_packet_alloc();
    AVPacket* audioOutputPacket = av_packet_alloc();
    if (!videoFrame || !audioFrame || !inputPacket || !videoOutputPacket || !audioOutputPacket) {
        std::cout << "分配帧对象失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        avcodec_free_context(&outAudioCodecContext);
        return false;
    }

    // 初始化像素格式转换器
    swsContext = sws_getContext(videoCodecContext->width, videoCodecContext->height, videoCodecContext->pix_fmt,
        outVideoCodecContext->width, outVideoCodecContext->height, outVideoCodecContext->pix_fmt,
        SWS_BILINEAR, nullptr, nullptr, nullptr);
    if (!swsContext) {
        std::cout << "初始化像素格式转换器失败" << std::endl;
        avformat_close_input(&inputFormatContext);
        avcodec_free_context(&videoCodecContext);
        avcodec_free_context(&audioCodecContext);
        avformat_free_context(outputFormatContext);
        avcodec_free_context(&outVideoCodecContext);
        avcodec_free_context(&outAudioCodecContext);
        av_frame_free(&videoFrame);
        av_frame_free(&audioFrame);
        av_packet_free(&inputPacket);
        av_packet_free(&videoOutputPacket);
        av_packet_free(&audioOutputPacket);
        return false;
    }

    // 解码并编码每一帧
    int ret = 0;
    int nVideoCount = 0;
    while (av_read_frame(inputFormatContext, inputPacket) >= 0) {
        if (inputPacket->stream_index == videoStreamIndex) {
            // 视频流处理
            ret = avcodec_send_packet(videoCodecContext, inputPacket);
            if (ret < 0) {
                break;
            }
            while (ret >= 0) {
                ret = avcodec_receive_frame(videoCodecContext, videoFrame);
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                    break;
                }
                else if (ret < 0) {
                    std::cout << "视频解码 ret 异常" << std::endl;
                    avformat_close_input(&inputFormatContext);
                    avcodec_free_context(&videoCodecContext);
                    avcodec_free_context(&audioCodecContext);
                    avformat_free_context(outputFormatContext);
                    avcodec_free_context(&outVideoCodecContext);
                    avcodec_free_context(&outAudioCodecContext);
                    av_frame_free(&videoFrame);
                    av_frame_free(&audioFrame);
                    av_packet_free(&inputPacket);
                    av_packet_free(&videoOutputPacket);
                    av_packet_free(&audioOutputPacket);
                    return false;
                }

                // 转换像素格式
                sws_scale(swsContext, videoFrame->data, videoFrame->linesize, 0, videoCodecContext->height,
                    videoFrame->data, videoFrame->linesize);
      
                // 编码视频帧
                videoFrame->pts = (int64_t)(40 * (nVideoCount) / av_q2d(outVideoCodecContext->time_base) / 1000.0);//时间
                nVideoCount++;
                ret = avcodec_send_frame(outVideoCodecContext, videoFrame);
                if (ret < 0) {
                    break;
                }

                while (ret >= 0) {
                    ret = avcodec_receive_packet(outVideoCodecContext, videoOutputPacket);
                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                        break;
                    }
                    else if (ret < 0) {
                        std::cout << "视频编码 ret 异常" << std::endl;
                        avformat_close_input(&inputFormatContext);
                        avcodec_free_context(&videoCodecContext);
                        avcodec_free_context(&audioCodecContext);
                        avformat_free_context(outputFormatContext);
                        avcodec_free_context(&outVideoCodecContext);
                        avcodec_free_context(&outAudioCodecContext);
                        av_frame_free(&videoFrame);
                        av_frame_free(&audioFrame);
                        av_packet_free(&inputPacket);
                        av_packet_free(&videoOutputPacket);
                        av_packet_free(&audioOutputPacket);
                        return false;
                    }

                    av_packet_rescale_ts(videoOutputPacket, outVideoCodecContext->time_base, outVideoStream->time_base);
                    videoOutputPacket->stream_index = outVideoStream->index;

                    // 写入视频帧到输出文件
                    ret = av_interleaved_write_frame(outputFormatContext, videoOutputPacket);
                    if (ret < 0) {
                        break;
                    }
                }
            }
        }
        else if (inputPacket->stream_index == audioStreamIndex) {
            // 音频流处理
            ret = avcodec_send_packet(audioCodecContext, inputPacket);
            if (ret < 0) {
                break;
            }

            while (ret >= 0) {
                ret = avcodec_receive_frame(audioCodecContext, audioFrame);
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                    break;
                }
                else if (ret < 0) {
                    std::cout << "音频解码 ret 异常" << std::endl;
                    avformat_close_input(&inputFormatContext);
                    avcodec_free_context(&videoCodecContext);
                    avcodec_free_context(&audioCodecContext);
                    avformat_free_context(outputFormatContext);
                    avcodec_free_context(&outVideoCodecContext);
                    avcodec_free_context(&outAudioCodecContext);
                    av_frame_free(&videoFrame);
                    av_frame_free(&audioFrame);
                    av_packet_free(&inputPacket);
                    av_packet_free(&videoOutputPacket);
                    av_packet_free(&audioOutputPacket);
                    return false;
                }

                // 编码音频帧
                ret = avcodec_send_frame(outAudioCodecContext, audioFrame);
                if (ret < 0) {
                    break;
                }

                while (ret >= 0) {
                    ret = avcodec_receive_packet(outAudioCodecContext, audioOutputPacket);
                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                        break;
                    }
                    else if (ret < 0) {
                        std::cout << "音频编码 ret 异常" << std::endl;
                        avformat_close_input(&inputFormatContext);
                        avcodec_free_context(&videoCodecContext);
                        avcodec_free_context(&audioCodecContext);
                        avformat_free_context(outputFormatContext);
                        avcodec_free_context(&outVideoCodecContext);
                        avcodec_free_context(&outAudioCodecContext);
                        av_frame_free(&videoFrame);
                        av_frame_free(&audioFrame);
                        av_packet_free(&inputPacket);
                        av_packet_free(&videoOutputPacket);
                        av_packet_free(&audioOutputPacket);
                        return false;
                    }

                    av_packet_rescale_ts(audioOutputPacket, outAudioCodecContext->time_base, outAudioStream->time_base);
                    audioOutputPacket->stream_index = outAudioStream->index;

                    // 写入音频帧到输出文件
                    ret = av_interleaved_write_frame(outputFormatContext, audioOutputPacket);
                    if (ret < 0) {
                        break;
                    }
                }
            }
        }

        av_packet_unref(inputPacket);
    }

    // 写入输出文件尾部
    av_write_trailer(outputFormatContext);

    // 释放资源
    av_frame_free(&videoFrame);
    av_frame_free(&audioFrame);
    av_packet_free(&inputPacket);
    av_packet_free(&videoOutputPacket);
    av_packet_free(&audioOutputPacket);

    avcodec_free_context(&videoCodecContext);
    avcodec_free_context(&audioCodecContext);
    avcodec_free_context(&outVideoCodecContext);
    avcodec_free_context(&outAudioCodecContext);

    avformat_close_input(&inputFormatContext);
    avformat_free_context(outputFormatContext);

    sws_freeContext(swsContext);

    return true;
}
int main() {
    // 输入文件名和输出文件名
    std::string inputFilename, outputFilename, Format;
    std::cout << "请输入输入文件名(带后缀):";
    std::cin >> inputFilename;
    std::cout << "请输入输出格式(avi,mp4,wmv,mkv,flv...):";
    std::cin >> Format;
    std::cout << "请输入输出文件名(带后缀):";
    std::cin >> outputFilename;
    if (!Format_conver(inputFilename, outputFilename, Format)) {
        std::cout << "Failed to convert!" << std::endl;
        return -1;
    }
    std::cout << "Conversion complete!" << std::endl;
    return 0;

}

这里我也想多转换点格式的,但是发现好像有点麻烦,就算了吧。里面主要是关于参数和时间戳的设计,我处理了很久是比较复杂的一点。一开始我想直接就用输入源的参数,参数太多了懒得一个一个报错了再去改,谁知道错的离谱,代码里面我自己设定了几个参数,可能不太全,但是代码可以运行了,结果也是准确的,还是不错的,毕竟自己也是刚开始学习。以后慢慢的接触的多了,再回来好好改现在存在的问题吧。

### 在 Windows 上使用 C++ 调用 FFmpeg 进行视频音频处理 为了在 Windows 平台上通过 C++ 成功调用 FFmpeg 处理音视频文件,需遵循特定的设置和编程实践。 #### 设置环境变量与动态链接库路径 确保 FFmpeg 的 DLL 文件被放置于系统的 PATH 环境变量中或者直接拷贝至 `C:\Windows\SysWOW64` 目录下以便程序能够找到并加载这些必要的共享库[^1]。这一步骤对于应用程序启动时自动定位所需的外部依赖至关重要。 #### 解决宏定义缺失问题 当遇到诸如 `-D__STDC_FORMAT_MACROS` 宏未定义的问题时,在项目源代码顶部添加如下预处理器指令可以有效解决问题: ```cpp #ifndef INT64_C #define INT64_C(c) (c ## LL) #define UINT64_C(c) (c ## ULL) #endif #if defined(__cplusplus) #define __STDC_CONSTANT_MACROS // common.h中的错误 #define __STDC_FORMAT_MACROS // timestamp.h中的错误 #endif ``` 上述代码片段应置于所有头文件之前以确保在整个编译单元范围内生效[^4]。 #### 初始化编码器上下文实例化对象 创建用于操作媒体流的核心组件——即编码器及其关联的数据结构体。下面给出了一段初始化 H.264 或 HEVC 编码器的标准做法作为参考: ```cpp AVCodec* pCodec = nullptr; AVCodecContext* pCodecCtx = nullptr; // 查找指定名称的编码器(例如:"libx264", "hevc_nvenc") pCodec = avcodec_find_encoder_by_name("h264"); // 可替换为其他支持的编码器名 if (!pCodec){ // 如果找不到对应的编码器,则终止执行 } else { // 分配新的编码器上下文 pCodecCtx = avcodec_alloc_context3(pCodec); // ...此处省略具体参数配置... } // 打开编码器准备就绪状态 avcodec_open2(pCodecCtx, pCodec, &dictParam); ``` 此部分逻辑来自一段典型的基于 FFmpeg SDK 开发的应用场景描述[^3]。注意这里仅展示了核心框架而忽略了详细的属性设定过程;实际应用中可能还需要根据需求调整更多选项来满足具体的业务要求。 #### 构建完整的工程解决方案 最后建议参照成熟的技术博客文章或官方文档指导完成整个项目的搭建工作,包括但不限于选择合适的构建工具链(如 MinGW-w64)、集成调试辅助插件以及优化性能等方面的内容[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值