macOS上使用qt creator编译调试ffmpeg.c

news2025/3/1 8:13:10

1 前言

    上文macOS上将ffmpeg.c编译成Framework介绍了使用xocde将ffmpeg.c编译成Framework的方法,这里列举另外一种办法,就是用qt creator来完成这件事情。

    编译环境如下:

  • qt creator 9.0.2;
  • ffmpeg release/6.1;

2 编译ffmpeg.c

    大致思路如下:

  • 将ffmpeg.c编译成动态库dylib;
  • 在qt creator的app工程里使用该动态库;

    值得一提的是,用qt creator新建工程,必须是Plain C Application,不能是C++的工程。因为ffmpeg.c相关头文件的变量名用到了c++的关键字,比如class等,这会导致在c++项目里无法编译成功。 

2.1 新建qt工程

    新建一个Plain C Application工程,并选择使用cmake来构建项目:

    代码目录结构如下图:

2.2 改写ffmpeg.c接口

    在ffmpeg.h文件中将main方法名改为ffmpeg:

#将main方法名改为ffmpeg
int ffmpeg(int argc, char* argv[]);

    在ffmpeg.c文件中将main方法名改为ffmpeg:

#将main方法名改为ffmpeg
int ffmpeg(int argc, char **argv)
{
    int ret, err_rate_exceeded;
    BenchmarkTimeStamps ti;

    init_dynload();

    setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */

    av_log_set_flags(AV_LOG_SKIP_REPEATED);
    parse_loglevel(argc, argv, options);

#if CONFIG_AVDEVICE
    avdevice_register_all();
#endif
    avformat_network_init();

    show_banner(argc, argv, options);

    /* parse options and open all input/output files */
    ret = ffmpeg_parse_options(argc, argv);
    if (ret < 0)
        goto finish;

    if (nb_output_files <= 0 && nb_input_files == 0) {
        show_usage();
        av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
        ret = 1;
        goto finish;
    }

    if (nb_output_files <= 0) {
        av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
        ret = 1;
        goto finish;
    }

    current_time = ti = get_benchmark_time_stamps();
    ret = transcode(&err_rate_exceeded);
    if (ret >= 0 && do_benchmark) {
        int64_t utime, stime, rtime;
        current_time = get_benchmark_time_stamps();
        utime = current_time.user_usec - ti.user_usec;
        stime = current_time.sys_usec  - ti.sys_usec;
        rtime = current_time.real_usec - ti.real_usec;
        av_log(NULL, AV_LOG_INFO,
               "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
               utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
    }

    ret = received_nb_signals ? 255 :
          err_rate_exceeded   ?  69 : ret;

finish:
    if (ret == AVERROR_EXIT)
        ret = 0;

    ffmpeg_cleanup(ret);
    return ret;
}

2.3 编写CMakeLists.txt

    用qt creator编译ffmpeg.c,关键在于cmake脚本的编写,这里贴出所写的cmake编译脚本:

cmake_minimum_required(VERSION 3.5)

project(qt-ffmpegc LANGUAGES C)

#ffmpeg源码根目录
set(FFMPEG_SRC_ROOT_PATH "/Users/mingo/Applications/workspace/av/ffmpeg")
#fftools源码目录
set(FFMPEG_SRC_TOOL_PATH ${FFMPEG_SRC_ROOT_PATH}/fftools)
#列出要参与编译的ffmpeg.c相关源码
set(FFMPEG_SRC
    ${FFMPEG_SRC_TOOL_PATH}/cmdutils.c ${FFMPEG_SRC_TOOL_PATH}/cmdutils.h
    ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_dec.c ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_demux.c
    ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_enc.c ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_filter.c
    ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_hw.c ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_mux_init.c
    ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_mux.c ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_mux.h
    ${FFMPEG_SRC_TOOL_PATH}/ffmpeg_opt.c ${FFMPEG_SRC_TOOL_PATH}/ffmpeg.c
    ${FFMPEG_SRC_TOOL_PATH}/ffmpeg.h
    ${FFMPEG_SRC_TOOL_PATH}/opt_common.c ${FFMPEG_SRC_TOOL_PATH}/opt_common.h
    ${FFMPEG_SRC_TOOL_PATH}/sync_queue.c ${FFMPEG_SRC_TOOL_PATH}/sync_queue.h
    ${FFMPEG_SRC_TOOL_PATH}/thread_queue.c ${FFMPEG_SRC_TOOL_PATH}/thread_queue.h
    ${FFMPEG_SRC_TOOL_PATH}/objpool.c ${FFMPEG_SRC_TOOL_PATH}/objpool.h)

#ffmpeg的头文件、lib文件及相关基础库根目录
set(FFMPEG_BUILD_ROOT_PATH ${FFMPEG_SRC_ROOT_PATH}/mac_build)
#ffmpeg几个库的include文件路径
set(FFMPEG_INCLUDE_PATH ${FFMPEG_BUILD_ROOT_PATH}/include)
#全部的依赖库所在目录
set(FFMPEG_LIB_PATH ${FFMPEG_BUILD_ROOT_PATH}/lib)

#系统基础库
set(SYS_BASE_LIB iconv z bz2)
#ffmpeg几个.a库
set(LINK_FFMPEG_LIBS
    ${FFMPEG_LIB_PATH}/libavformat.a
    ${FFMPEG_LIB_PATH}/libavutil.a
    ${FFMPEG_LIB_PATH}/libavcodec.a
    ${FFMPEG_LIB_PATH}/libavfilter.a
    ${FFMPEG_LIB_PATH}/libswscale.a
    ${FFMPEG_LIB_PATH}/libswresample.a
    ${FFMPEG_LIB_PATH}/libavdevice.a)
#其他依赖库
set(OTHER_3RDPARTY_LIBS
    ${FFMPEG_LIB_PATH}/libxcb.a
    ${FFMPEG_LIB_PATH}/libxcb-xfixes.a
    ${FFMPEG_LIB_PATH}/libxcb-shm.a
    ${FFMPEG_LIB_PATH}/libxcb-shape.a
    ${FFMPEG_LIB_PATH}/libXdmcp.a
    ${FFMPEG_LIB_PATH}/libXau.a
    ${FFMPEG_LIB_PATH}/libX11.a
    ${FFMPEG_LIB_PATH}/libX11-xcb.a
    ${FFMPEG_LIB_PATH}/libSDL2.dylib)

#将ffmpeg.c打成动态库
add_library(ffmpegc SHARED ${FFMPEG_SRC})
#指定ffmpegc动态库相关依赖库
target_link_libraries(ffmpegc PRIVATE ${LINK_FFMPEG_LIBS} ${OTHER_3RDPARTY_LIBS} ${SYS_BASE_LIB})
#ffmpeg所依赖的macOS的Framework
list(APPEND DEPENDCY_LIB_LIST
    Foundation AudioToolbox CoreAudio AVFoundation CoreVideo CoreMedia CoreGraphics OpenGL Metal VideoToolbox CoreImage AppKit CoreFoundation CoreServices Security)
foreach(var IN LISTS DEPENDCY_LIB_LIST)
    target_link_libraries(ffmpegc PRIVATE "-framework ${var}")
endforeach()
# 设置ffmpeg.c动态库的输出路径
set_target_properties(ffmpegc PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY ${FFMPEG_LIB_PATH}
    ARCHIVE_OUTPUT_DIRECTORY ${FFMPEG_LIB_PATH}
)

add_executable(qt-ffmpegc main.c)

include_directories(${FFMPEG_SRC_ROOT_PATH})
include_directories(${FFMPEG_SRC_TOOL_PATH})
include_directories(${FFMPEG_INCLUDE_PATH})

#指定qt-ffmpegc app工程所依赖的库,与ffmpeg.c一致
target_link_libraries(qt-ffmpegc PRIVATE ${LINK_FFMPEG_LIBS} ${OTHER_3RDPARTY_LIBS} ${SYS_BASE_LIB})
#qt-ffmpegc依赖ffmpegc动态库
target_link_libraries(qt-ffmpegc PRIVATE ${FFMPEG_LIB_PATH}/libffmpegc.dylib)
#qt-ffmpegc依赖macOS的各framwork
foreach(var IN LISTS DEPENDCY_LIB_LIST)
    message(STATUS ${var})
    target_link_libraries(qt-ffmpegc PRIVATE "-framework ${var}")
endforeach()

install(TARGETS qt-ffmpegc
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

    值得一提的是,cmake脚本里指定对macOS系统Framework的依赖脚本如下,列出范例代码:

target_link_libraries(qt-ffmpegc PRIVATE "-framework Foundation")

    好了,cmake脚本编写完成,现在可以编译ffmpeg.c动态库和qt-ffmpegc可执行文件了。

3 使用ffmpeg.c动态库

    列出qt-ffmpegc工程main.c的调用代码:

#include <stdio.h>

#include "libavformat/avformat.h"
#include "ffmpeg.h"

static void test_ffmpeg() {
    AVFormatContext* ifmt = NULL;
    const char* filename = "";
    int ret = avformat_open_input(&ifmt, filename, NULL, NULL);
    if (ret < 0) {
        av_log(ifmt, AV_LOG_INFO, "avformat_open_input failed\n");
    }
    ret = avformat_find_stream_info(ifmt, NULL);
    if (ret < 0) {

    }

    AVPacket pkt;
    av_init_packet(&pkt);
    while (1) {
        ret = av_read_frame(ifmt, &pkt);
        if (pkt.stream_index == 1 &&  pkt.flags & AV_PKT_FLAG_KEY) {
            av_log(ifmt, AV_LOG_INFO, "keyframe\n");
        }
    }
}

static void test_ffmpeg_cmd(int argc, const char* argv[]) {
    ffmpeg(argc, argv);
}

int main()
{
    printf("Hello World!\n");
    test_ffmpeg();
    const char* args[3] = { "ffmpeg", "-h", "filter=overlay" };
    test_ffmpeg_cmd(3, args);
    return 0;
}

    然后编译调试,执行ffmpeg -h filter=overlay范例命令:

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

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

相关文章

应用层(上篇)

应用层 应用层协议原理 网络应用程序体系解构 应用程序体系结构: 由应用程序研发者设计规定了如何在各种端系统上组织该应用程序。在选择应用程序体系结构时&#xff0c;应用程序研发者很可能利用现代网络应用程序中所使用的两种主流体系结构之一:客户-服务器体系结构或对等…

C语言例题41、八进制转换为十进制

#include<stdio.h>void main() {int x;printf("请输入一个8进制整数&#xff1a;");scanf("%o", &x);printf("转换成十进制后的整数为%d\n", x); }运行结果&#xff1a; 本章C语言经典例题合集&#xff1a;http://t.csdnimg.cn/FK0Qg…

网上办理无犯罪证明

在微信小程序 搜 比如 河南 就搜 河南无犯罪证明&#xff0c;这个时候会出现一个公众号&#xff0c;进去之后注册一个账号和密码&#xff1b;登录成功后并找到无犯罪证明&#xff0c;按照人家的操作步骤进行操作&#xff1b;最终预约成功后 几个工作日会给你发一个电子版的无犯…

【Python】一文详细介绍 pkl格式 文件

【Python】一文详细介绍 pkl格式 文件 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订阅和支持~ &#x…

(八)SQL基础知识练习题(选择题)(下)#CDA学习打卡

本文整理了SQL基础知识相关的练习题&#xff0c;共133道&#xff0c;可作为CDA一级的补充习题&#xff0c;也适用于刚入门初级SQL想巩固基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-SQL&#xff09;。暂时按照原题库顺序present&#xff0c;如有需要之…

【每日刷题】Day40

【每日刷题】Day40 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 2. 217. 存在重复元素 - 力扣&#xff08;Le…

优选算法——双指针1

双指针 常⻅的双指针有两种形式&#xff0c;⼀种是对撞指针&#xff0c;⼀种是左右指针。 对撞指针&#xff1a;⼀般⽤于顺序结构中&#xff0c;也称左右指针。 对撞指针从两端向中间移动。⼀个指针从最左端开始&#xff0c;另⼀个从最右端开始&#xff0c;然后逐渐往中间逼 近…

Linux提权--Rsync(未授权访问) Docker 组挂载

免责声明:本文仅做技术学习与交流... 目录 Rsync&#xff08;未授权访问&#xff09; 介绍: 靶场及过程: 提权过程&#xff1a; Docker 组挂载 原理: 复现&#xff1a; 利用&#xff1a; 具体操作: 1-确定是否有docker服务 2-查看用户是否在docker组里面 3-执行命…

Raft论文阅读笔记+翻译:In Search of Understandable Consensus Algorithm

In Search of Understandable Consensus Algorithm 摘要 Raft是一种管理复制日志的共识算法。它产生与&#xff08;多&#xff09;Paxos等效的结果&#xff0c;并且与Paxos一样高效&#xff0c;但其结构与Paxos不同。这使得Raft比Paxos更易理解&#xff0c;也为构建实际系统提供…

面试官:假如有几十个请求,如何去控制并发?

控制并发请求是一个重要的问题&#xff0c;特别是在面对高并发情况时&#xff0c;合理地管理请求可以有效地维护系统的稳定性和性能。以下是一些常见的方法来控制并发请求&#xff1a; 1. 线程池&#xff1a;使用线程池来管理并发请求&#xff0c;通过限制线程数量和队列大小&…

ComfyUI相见恨晚的提示词插件,简直堪称神器!

之前我曾介绍过一款专为SD设计的中文提示词插件——prompt-all-in-one&#xff0c;想必使用过的小伙伴们都已经感受到了它的便捷与实用吧。 不过&#xff0c;那款插件是基于webUI版本的&#xff0c;而现在&#xff0c;越来越多的朋友开始探索ComfyUI这一新选择。 假如在Comfy…

C++基础与深度解析 | 数组 | vector | string

文章目录 一、数组1.一维数组2.多维数组 二、vector三、string 一、数组 1.一维数组 在C中&#xff0c;数组用于存储具有相同类型和特定大小的元素集合。数组在内存中是连续存储的&#xff0c;并且支持通过索引快速访问元素。 数组的声明&#xff1a; 数组的声明指定了元素的…

virtualBox不能创建虚拟文件夹

问题如下图&#xff0c;在点击下一步时提示不能创建虚拟机文件夹 问题原因是使用了virtualBox的安装目录&#xff0c;在全局设定中设置虚拟电脑位置&#xff0c;不再使用virtualBox的安装目录 再次点击新建&#xff0c;就可以创建了。

无线网卡网络老断网

无线网卡网络老断网 设置 Intel AX210 无线网卡 路由器华为 AX3 问题及解决 问题 无线网卡连接到 wifi &#xff0c;连接不通&#xff0c;或者连接上后网络很慢&#xff0c;延时大&#xff0c;掉包。 解决方案 调整如下界面&#xff0c;调整信道后&#xff0c;连接正常。…

亚马逊卖家,如何打造爆款,如何提高产品权重、曝光、流量?

新老卖家们要知道&#xff0c;亚马逊A9算法影响产品排名的关键因素&#xff1a;产品相关性、销售排名、产品价格、点击率、转化率、产品图片、买家评论、买家满意度、QA的答复情况、搜索结果页详细信息级别。亚马逊A9算法&#xff0c;是根据卖家提供的listing文案信息进行收录、…

常见加解密算法02 - RC4算法分析

RC4是一种广泛使用的流密码&#xff0c;它以其简洁和速度而闻名。区别于块密码&#xff0c;流密码特点在于按位或按字节来进行加密。 RC4由Ron Rivest在1987年设计&#xff0c;尽管它的命名看起来是第四版&#xff0c;实际上它是第一个对外发布的版本。 RC4算法的实施过程简洁…

动态el-form表单以及动态禁用

当右侧下拉框选中为 长期有效,那么左侧输入框为禁用状态; <el-form-item label"证明有效期" class"is-required"><div v-for"(item,index) in form.arrayDat" :key"index" style"width: 100%;display: flex;justify-co…

深度解读《深度探索C++对象模型》之虚继承的实现分析和效率评测(二)

目录 通过子类的指针存取虚基类成员的实现分析 通过第一基类的指针存取虚基类成员的实现分析 通过第二基类的指针存取虚基类成员的实现分析 通过虚基类的指针存取虚基类成员的实现分析 小结 存取虚基类成员与普通类成员的效率对比 接下来我将持续更新“深度解读《深度探索…

WS2812B-2020 智能控制LED集成光源芯片IC

一般说明 WS2812B-2020是一款智能控制LED光源&#xff0c;它的外部采用了最新的模压封装技术&#xff0c;控制电路和RGB芯片集成在一个2020组件中。其内部包括智能数字端口数据锁存器和信号整形放大驱动电路。还包括一个精密的内部振荡器和一个电压可编程恒流控制部分&…

对关系型数据库管理系统的介绍

1.数据库的相关介绍 关系型数据库管理系统&#xff1a;&#xff08;英文简称&#xff1a;RDBMS&#xff09; 为我们提供了一种存储数据的特定格式&#xff0c;所谓的数据格式就是表&#xff0c; 在数据库中一张表就称为是一种关系. 在关系型数据库中表由两部分组成&#xf…