C++ CMake FFmpeg配置

news2024/11/15 7:50:55
SDK下载  github

环境变量配置

cmake_modules/FindFFmpeg.cmake
# This module defines the following variables:
#
# FFmpeg_FOUND          - All required components and the core library were found
# FFmpeg_INCLUDE_DIRS   - Combined list of all components include dirs
# FFmpeg_LIBRARIES      - Combined list of all components libraries
# FFmpeg_VERSION        - Version defined in libavutil/ffversion.h
#
# ffmpeg::ffmpeg        - FFmpeg target
#
# For each requested component the following variables are defined:
#
# FFmpeg_<component>_FOUND          - The component was found
# FFmpeg_<component>_INCLUDE_DIRS   - The components include dirs
# FFmpeg_<component>_LIBRARIES      - The components libraries
# FFmpeg_<component>_VERSION        - The components version
#
# ffmpeg::<component>               - The component target
#
# Usage:
#   find_package(FFmpeg REQUIRED)
#   find_package(FFmpeg 5.1.2 COMPONENTS avutil avcodec avformat avdevice avfilter REQUIRED)

find_package(PkgConfig QUIET)

# find the root dir for specified version
function(find_ffmpeg_root_by_version EXPECTED_VERSION)
    set(FFMPEG_FIND_PATHS $ENV{PATH} $ENV{FFMPEG_PATH} $ENV{FFMPEG_ROOT} /opt /usr /sw)

    set(FOUND_VERSION)
    set(FOUND_ROOT_DIR)

    foreach(ROOT_DIR ${FFMPEG_FIND_PATHS})
        unset(FFMPEG_VERSION_HEADER CACHE)
        find_file(
            FFMPEG_VERSION_HEADER
            NAMES "ffversion.h"
            PATHS ${ROOT_DIR} ${ROOT_DIR}/include ${ROOT_DIR}/include/${CMAKE_LIBRARY_ARCHITECTURE}
            PATH_SUFFIXES libavutil
            NO_DEFAULT_PATH
        )
        mark_as_advanced(FFMPEG_VERSION_HEADER)

        if(NOT "${FFMPEG_VERSION_HEADER}" STREQUAL "FFMPEG_VERSION_HEADER-NOTFOUND")
            file(STRINGS "${FFMPEG_VERSION_HEADER}" FFMPEG_VERSION_STRING REGEX "FFMPEG_VERSION")

            # #define FFMPEG_VERSION "6.0-full_build-www.gyan.dev"
            # fixme:    #define FFMPEG_VERSION "N-111059-gd78bffbf3d"
            string(REGEX REPLACE "#define FFMPEG_VERSION[ \t]+\"[n]?([0-9\\.]*).*\"" "\\1" CURRENT_VERSION "${FFMPEG_VERSION_STRING}")
            set(CURRENT_VERSION ${FFmpeg_FIND_VERSION})
            # not specified, return the first one
            if("${EXPECTED_VERSION}" STREQUAL "")
                set(FOUND_VERSION ${CURRENT_VERSION})
                set(FOUND_ROOT_DIR ${ROOT_DIR})
                break()
            endif()

            # otherwise, the minimum one of suitable versions
            if(${CURRENT_VERSION} VERSION_GREATER_EQUAL "${EXPECTED_VERSION}")
                if((NOT FOUND_VERSION) OR(${CURRENT_VERSION} VERSION_LESS "${FOUND_VERSION}"))
                    set(FOUND_VERSION ${CURRENT_VERSION})
                    set(FOUND_ROOT_DIR ${ROOT_DIR})
                endif()
            endif()
        endif()
    endforeach()

    set(FFmpeg_VERSION ${FOUND_VERSION} PARENT_SCOPE)
    set(FFmpeg_ROOT_DIR ${FOUND_ROOT_DIR} PARENT_SCOPE)
endfunction()

# find a ffmpeg component
function(find_ffmpeg_component ROOT_DIR COMPONENT HEADER)
    # header
    find_path(
        FFmpeg_${COMPONENT}_INCLUDE_DIR
        NAMES "lib${COMPONENT}/${HEADER}" "lib${COMPONENT}/version.h"
        PATHS ${ROOT_DIR} ${ROOT_DIR}/include/${CMAKE_LIBRARY_ARCHITECTURE}
        PATH_SUFFIXES ffmpeg libav include
        NO_DEFAULT_PATH
    )

    # version
    if(EXISTS "${FFmpeg_${COMPONENT}_INCLUDE_DIR}/lib${COMPONENT}/version.h")
        if(EXISTS "${FFmpeg_${COMPONENT}_INCLUDE_DIR}/lib${COMPONENT}/version_major.h")
            file(STRINGS "${FFmpeg_${COMPONENT}_INCLUDE_DIR}/lib${COMPONENT}/version_major.h" MAJOR_VERSION_STRING REGEX "^.*VERSION_MAJOR[ \t]+[0-9]+[ \t]*$")
        endif()

        # other
        file(STRINGS "${FFmpeg_${COMPONENT}_INCLUDE_DIR}/lib${COMPONENT}/version.h" VERSION_STRING REGEX "^.*VERSION_(MAJOR|MINOR|MICRO)[ \t]+[0-9]+[ \t]*$")

        list(APPEND VERSION_STRING ${MAJOR_VERSION_STRING})

        string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" MAJOR "${VERSION_STRING}")
        string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" MINOR "${VERSION_STRING}")
        string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" PATCH "${VERSION_STRING}")

        set(FFmpeg_${COMPONENT}_VERSION "${MAJOR}.${MINOR}.${PATCH}" PARENT_SCOPE)
    else()
        message(STATUS "'${FFmpeg_${COMPONENT}_INCLUDE_DIR}/lib${COMPONENT}/version.h' does not exist.")
    endif()

    # library
    if(WIN32)
        find_library(
            FFmpeg_${COMPONENT}_IMPLIB
            NAMES "${COMPONENT}" "lib${COMPONENT}"
            PATHS ${ROOT_DIR} ${ROOT_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE}
            PATH_SUFFIXES lib lib64 bin bin64
            NO_DEFAULT_PATH
        )

        find_program(
            FFmpeg_${COMPONENT}_LIBRARY
            NAMES "${COMPONENT}-${MAJOR}.dll" "${COMPONENT}.dll"
            PATHS ${ROOT_DIR} ${ROOT_DIR}/bin
            NO_DEFAULT_PATH
        )
    else()
        find_library(
            FFmpeg_${COMPONENT}_LIBRARY
            NAMES "${COMPONENT}" "lib${COMPONENT}"
            PATHS ${ROOT_DIR} ${ROOT_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE}
            PATH_SUFFIXES lib lib64 bin bin64
            NO_DEFAULT_PATH
        )
    endif()

    mark_as_advanced(FFmpeg_${COMPONENT}_INCLUDE_DIR FFmpeg_${COMPONENT}_LIBRARY FFmpeg_${COMPONENT}_IMPLIB)

    if(FFmpeg_${COMPONENT}_INCLUDE_DIR AND FFmpeg_${COMPONENT}_LIBRARY)
        set(FFmpeg_${COMPONENT}_FOUND TRUE PARENT_SCOPE)

        set(FFmpeg_${COMPONENT}_IMPLIBS ${FFmpeg_${COMPONENT}_IMPLIB} PARENT_SCOPE)
        set(FFmpeg_${COMPONENT}_LIBRARIES ${FFmpeg_${COMPONENT}_LIBRARY} PARENT_SCOPE)
        set(FFmpeg_${COMPONENT}_INCLUDE_DIRS ${FFmpeg_${COMPONENT}_INCLUDE_DIR} PARENT_SCOPE)
    endif()
endfunction()

# start finding
if(NOT FFmpeg_FIND_COMPONENTS)
    list(APPEND FFmpeg_FIND_COMPONENTS avutil avcodec avdevice avfilter avformat swresample swscale postproc)
endif()

find_ffmpeg_root_by_version("${FFmpeg_FIND_VERSION}")

if((NOT FFmpeg_VERSION) OR(NOT FFmpeg_ROOT_DIR))
    message(FATAL_ERROR "Can not find the suitable version.")
endif()

list(REMOVE_DUPLICATES FFmpeg_FIND_COMPONENTS)

foreach(COMPONENT ${FFmpeg_FIND_COMPONENTS})
    if(COMPONENT STREQUAL "postproc")
        find_ffmpeg_component(${FFmpeg_ROOT_DIR} ${COMPONENT} "postprocess.h")
    else()
        find_ffmpeg_component(${FFmpeg_ROOT_DIR} ${COMPONENT} "${component}.h")
    endif()

    if(FFmpeg_${COMPONENT}_FOUND)
        list(APPEND FFmpeg_LIBRARIES ${FFmpeg_${COMPONENT}_LIBRARIES})
        list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${COMPONENT}_INCLUDE_DIRS})
    endif()
endforeach()

list(REMOVE_DUPLICATES FFmpeg_LIBRARIES)
list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS)

#
include(FindPackageHandleStandardArgs)

find_package_handle_standard_args(
    FFmpeg
    FOUND_VAR FFmpeg_FOUND
    REQUIRED_VARS FFmpeg_ROOT_DIR FFmpeg_INCLUDE_DIRS FFmpeg_LIBRARIES
    VERSION_VAR FFmpeg_VERSION
    HANDLE_COMPONENTS
)

if(FFmpeg_FOUND)
    if(NOT TARGET ffmpeg::ffmpeg)
        add_library(ffmpeg::ffmpeg INTERFACE IMPORTED)
    endif()

    foreach(component IN LISTS FFmpeg_FIND_COMPONENTS)
        if(FFmpeg_${component}_FOUND AND NOT TARGET ffmpeg::${component})
            if(IS_ABSOLUTE "${FFmpeg_${component}_LIBRARIES}")
                if(DEFINED FFmpeg_${component}_IMPLIBS)
                    if(FFmpeg_${component}_IMPLIBS STREQUAL FFmpeg_${component}_LIBRARIES)
                        add_library(ffmpeg::${component} STATIC IMPORTED)
                    else()
                        add_library(ffmpeg::${component} SHARED IMPORTED)
                        set_property(TARGET ffmpeg::${component} PROPERTY IMPORTED_IMPLIB "${FFmpeg_${component}_IMPLIBS}")
                    endif()
                else()
                    add_library(ffmpeg::${component} UNKNOWN IMPORTED)
                endif()

                set_property(TARGET ffmpeg::${component} PROPERTY IMPORTED_LOCATION "${FFmpeg_${component}_LIBRARIES}")
            else()
                add_library(ffmpeg::${component} INTERFACE IMPORTED)
                set_target_properties(ffmpeg::${component} PROPERTIES IMPORTED_LIBNAME "${FFmpeg_${component}_LIBRARIES}")
            endif()

            set_target_properties(ffmpeg::${component} PROPERTIES
                INTERFACE_INCLUDE_DIRECTORIES "${FFmpeg_${component}_INCLUDE_DIRS}"
                VERSION "${FFmpeg_${component}_VERSION}"
            )

            get_target_property(FFMPEG_INTERFACE_LIBRARIES ffmpeg::ffmpeg INTERFACE_LINK_LIBRARIES)

            if(NOT ffmpeg::${component} IN_LIST FFMPEG_INTERFACE_LIBRARIES)
                set_property(TARGET ffmpeg::ffmpeg APPEND PROPERTY INTERFACE_LINK_LIBRARIES ffmpeg::${component})
            endif()
        endif()
    endforeach()
endif()
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

# 设置项目名称
project(MyFFmpegExample VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
find_package(FFmpeg 6 REQUIRED)
target_link_libraries(test
    PRIVATE
        ffmpeg::ffmpeg
)
add_executable(${PROJECT_NAME} main.cpp)
main.cpp 
#include <iostream>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>

using namespace std;

int main(int argc, char** argv) {
    if (argc != 2) {
        cerr << "Usage: " << argv[0] << " <input-file>" << endl;
        return 1;
    }

    const char* input_filename = argv[1];

    // 初始化 FFmpeg 库
    av_register_all();
    avformat_network_init();

    // 打开输入文件
    AVFormatContext* format_ctx = nullptr;
    if (avformat_open_input(&format_ctx, input_filename, nullptr, nullptr) != 0) {
        cerr << "Could not open input file." << endl;
        return 1;
    }

    // 获取文件信息
    if (avformat_find_stream_info(format_ctx, nullptr) < 0) {
        cerr << "Failed to retrieve input stream information." << endl;
        return 1;
    }

    // 查找视频流
    int video_stream = -1;
    for (unsigned int i = 0; i < format_ctx->nb_streams; i++) {
        if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_stream = i;
            break;
        }
    }

    if (video_stream == -1) {
        cerr << "No video stream found." << endl;
        return 1;
    }

    // 获取视频编解码器上下文
    AVCodecParameters* codecpar = format_ctx->streams[video_stream]->codecpar;
    const AVCodec* decoder = avcodec_find_decoder(codecpar->codec_id);
    if (!decoder) {
        cerr << "Failed to find decoder for the video stream." << endl;
        return 1;
    }

    AVCodecContext* codec_ctx = avcodec_alloc_context3(decoder);
    if (avcodec_parameters_to_context(codec_ctx, codecpar) < 0) {
        cerr << "Failed to copy codec parameters to codec context." << endl;
        return 1;
    }

    // 打开编解码器
    if (avcodec_open2(codec_ctx, decoder, nullptr) < 0) {
        cerr << "Failed to open decoder." << endl;
        return 1;
    }

    // 分配帧
    AVFrame* frame = av_frame_alloc();

    // 分配包
    AVPacket packet;
    av_init_packet(&packet);

    // 逐帧解码
    int frame_count = 0;
    while (av_read_frame(format_ctx, &packet) >= 0) {
        if (packet.stream_index == video_stream) {
            // 解码帧
            if (avcodec_send_packet(codec_ctx, &packet) == 0) {
                while (avcodec_receive_frame(codec_ctx, frame) == 0) {
                    // 输出帧信息
                    cout << "Decoded frame " << ++frame_count << endl;

                    // 重置包
                    av_packet_unref(&packet);
                }
            }
        }

        // 重置包
        av_packet_unref(&packet);
    }

    // 清理
    avcodec_free_context(&codec_ctx);
    av_frame_free(&frame);
    avformat_close_input(&format_ctx);

    return 0;
}


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2034574.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Dijkstra单源最短路径算法学习有感

认识Dijkstra 艾兹格维布迪克斯特拉&#xff08;Edsger Wybe Dijkstra&#xff0c;/ˈdaɪkstrə/ DYKE-strə&#xff1b;荷兰语&#xff1a;[ˈɛtsxər ˈʋibə ˈdɛikstra] 1930年5月11日-2002年8月6日&#xff09;是一位荷兰计算机科学家、程序员、软件工程师、系统科学…

(回溯) LeetCode 46. 全排列

原题链接 一. 题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#xff1a;…

零基础学习Redis(1) -- Redis简介

Redis是一个在内存中存储数据的一个中间组件&#xff0c;可用作数据库或数据缓存&#xff0c;通常在分布式系统中使用 &#xff08;不了解分布式&#xff1f; 点击传送&#xff09; 1. Redis特性 在内存中存储数据&#xff0c;通过键值对的方法存储key为string&#xff0c;v…

[GYCTF2020]FlaskApp1

打开题目 简单的一个base64加解密小程序 查看提示&#xff0c;好像并没有什么用&#xff0c;题目是flask&#xff0c;可能是ssti模板注入 加密窗口{{77}},解密窗口e3s3Kzd9fQ ({{77}} 加密窗口没看到注入&#xff0c;解密窗口存在注入&#xff0c;是模板注入 读取文件内容&am…

JimV私有云平台部署及应用

1. JimV概述 1.1 介绍 JimV 是一个&#xff0c;结构精简&#xff0c;易于部署、维护、使用的&#xff0c;企业私有云管理平台。JimV 基于 KVM 开发而来&#xff0c;通过 JimV 管理平台&#xff0c;可以批量创建、管理虚拟机。 JimV 更为轻量级&#xff0c;使用户轻易拥有维护…

【Day05】0基础微信小程序入门-学习笔记

文章目录 基础加强学习目标使用npm包1.准备项目2. 小程序对于npm的支持和限制3. Vant Weapp小程序UI组件库4. 使用Vant组件5. 定制全局主题样式6. API Promise化 全局数据共享1. 简介2. MobX2.1 安装MobX相关包并构建npm2.2 创建MobX的Store实例2.3 将Store成员绑定到页面中2.4…

SpringBoot统一功能

目录 前言1&#xff1a;首先要明白&#xff0c;什么是统一功能&#xff1f; 前言2&#xff1a;统一功能包括哪些呢&#xff1f;展开说说&#xff1f; 一、拦截器&#xff08;interceptor&#xff09; 1、介绍 2、如何使用拦截器 3、拦截器的在程序内部的执行流程是啥呢&a…

MySQL关键字—using和on

文章目录 1. MySQL关键字—using和on1.1 using关键字的概念 2. using和on的区别2.1 USING 子句2.2 ON 子句 3. 示例对比3.1 建表&#xff1a;3.2 准备数据3.3 结果 1. MySQL关键字—using和on 1.1 using关键字的概念 连接查询时如果是同名字段作为连接条件&#xff0c;using可…

ctfhub Bypass disable_function(完结)0

LD_PRELOAD url 蚁剑连接 选择插件 点击开始 查看到此文件名编辑连接拼接到url后面重新连接 点击开启终端 在终端执行命令 ls / /readfile ShellShock url CTFHub 环境实例 | 提示信息 蚁剑连接 写入shell.php <?phpeval($_REQUEST[ant]);putenv("PHP_test() { :…

四款AI写作免费工具,让文案工作更轻松

作为一名文案编辑&#xff0c;我算是跟文字打了几年的交道了。最近&#xff0c;AI写作这股风潮真是吹得热火朝天&#xff0c;我也忍不住尝了尝鲜&#xff0c;试了试几款神器。说实话&#xff0c;这体验还挺有意思的&#xff0c;感觉就像是在文字的世界里开了一场高科技的派对。…

Redis:概念、部署、配置、优化

目录 关系型数据库与非关系型数据库 关系型数据库 非关系型数据库 非关系型数据库存在的原因 Redis 概念 优点 Redis部署流程 初步设置 安装 初始化 初始化时指定的参数说明 Redis配置文件 修改监听地址 Redis远程连接 远程连接 测试服务端状态 redis-benchm…

智慧景区系统:科技赋能旅游新体验

随着信息技术的飞速发展&#xff0c;旅游业正经历着前所未有的变革&#xff0c;智慧景区系统作为这一变革的先锋&#xff0c;正以其独特的魅力重塑着游客的旅行方式。智慧景区系统&#xff0c;顾名思义&#xff0c;是运用物联网、大数据、云计算、人工智能等现代信息技术&#…

Git客户端 TortoiseGit下载

1.概述 使用TortoiseGit比直接使用git客户端和命令来实现代码管理更为方便&#xff0c;本文贴出了软件的下载地址和基本配置信息 2.TortoiseGit安装与配置 TortoiseGit是TortoiseSVN的Git版本&#xff0c;是一个在Windows系统下使用的Git版本控制客户端。它提供了图形用户界…

MIT线性代数P5

置换矩阵 置换矩阵是行重新排列的单位矩阵。 置换矩阵用P表示&#xff0c; 性质&#xff1a; n阶置换矩阵共有n!个

37.x86游戏实战-XXX遍历怪物数组

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

0812|TCP和UDP跨主机通信

思维导图 TCP实现跨主机通信 服务器端 #include<myhead.h> #define SER_PORT 6666 //端口号 #define SER_IP "192.168.0.108" //服务器IP int main(int argc, const char *argv[]) {//创建套接字文件int sfd socket(AF_INET,SOCK_STREAM,0);if(sfd -1){pe…

进阶!haproxy高级功能与配置

文章目录 前言基于cookie的会话保持IP透传四层IP透传未开启状态开启透传状态 七层IP透传 自定义错误界面重定向HAProxy 四层负载之数据库HAProxy https 前言 本文主要介绍HAProxy高级配置及使用案例 文章相关连接如下&#xff1a; 如果想深入了解haproxy算法的相关知识&…

基于Python+Django+Vue+Mysql前后端分离的图书管理系统

利用空闲休息时间开始自己写了一套图书管理系统。现将源码开源&#xff0c;项目遇到问题 PythonDjangoVue图书管理系统开发全流程 大家好&#xff0c;我是程序员科科&#xff0c;这是我开源的基于PythonDjangoVue的图书管理系统 希望可以帮助想学前后端分离的同学 项目中遇…

积极创新模式,推动智慧场馆建设

智慧场馆是指基于信息技术应用的场馆建设模式&#xff0c;利用物联网、云计算、大数据分析等技术手段&#xff0c;实现场馆资源的管理优化、运营效率的提升以及用户体验的改善。智慧场馆在我国得到了广泛的政策支持和推动&#xff0c;政府出台了一系列鼓励智慧场馆建设的政策措…

Java SIP Client

采用JAIN SIP API实现一个SIP客户端实现向SIP服务器注册。SIP服务器可以为FreeSWITCH也可以为满足GB28181的SIP平台。话不多说直接看注册流程图&#xff1a; 代码实现&#xff1a; 创建maven工程添加依赖 <dependencies><dependency><groupId>javax.sip</…