FFmpeg: 简易ijkplayer播放器实现--05ijkplayer–连接UI界面和ffplay.c

news2024/11/24 0:13:29

文章目录

      • ijkplayer时序图
      • 消息循环--回调函数实现
      • 播放器播放时状态转换
        • 播放
        • 停止
      • ijkmediaPlay
        • 成员变量
        • 成员函数

ijkplayer时序图

请添加图片描述
stream_open:
frame_queue_init
packet_queue_init
init_clock
创建read_thread线程
创建video_refresh_thread线程

消息循环–回调函数实现

ui 和播放器核心直接的交互有以下几种方式:

  1. ui直接调用IjkMediaPlayer的接口
  2. ui发送消息给消息循环线程,然后调⽤IjkMediaPlayer的接口
  3. IjkMediaPlayer发消息给消息循环线程,线程调⽤ui的接口

UI发送消息给循环线程,通过c++11中bind实现回调函数:
void MainWind::OnPlayOrPause() {
mp_ = new IjkMediaPlayer();
mp_->ijkmp_create(std::bind(&MainWind::message_loop, this, std::placeholders::_1))
mp_->ijkmp_prepare_async();

}

ijkmp_create: msg_loop函数赋值给ijkMediaPlay函数指针msg_loop
int IjkMediaPlayer::ijkmp_create(std::function<int (void *)> msg_loop)
{
msg_loop_ = msg_loop;
}

ijkMediaPlay的成员函数ijk_msg_loop,调用msg_loop_函数指针
int IjkMediaPlayer::ijkmp_msg_loop(void *arg)
{
msg_loop_(arg);
return 0;
}

jikMediaPlay在ijkmp_prepare_async中启动线程,调用ijk_msg_loop
int IjkMediaPlayer::ijkmp_prepare_async()
{
// 创建循环线程
msg_thread_ = new std::thread(&IjkMediaPlayer::ijkmp_msg_loop, this, this);
}

至此,调用MainWind中调用ijkmp_prepare_async即可实现message_loop消息循环函数回调

void MainWind::OnPlayOrPause()
{
    qDebug() << "OnPlayOrPause call";
    int ret = 0;
    // 1. 先检测mp是否已经创建
    if(!mp_) {
        mp_ = new IjkMediaPlayer();
        //1.1 创建
        ret = mp_->ijkmp_create(std::bind(&MainWind::message_loop, this, std::placeholders::_1));
        if(ret <0) {
            qDebug() << "IjkMediaPlayer create failed";
            delete mp_;
            mp_ = NULL;
            return;
        }
        // 1.2 设置url
        mp_->ijkmp_set_data_source("2_audio.mp4");
        // 1.3 准备工作
        ret = mp_->ijkmp_prepare_async();
        if(ret <0) {
            qDebug() << "IjkMediaPlayer create failed";
            delete mp_;
            mp_ = NULL;
            return;
        }
    } else {
        // 已经准备好了,则暂停或者恢复播放
    }
}

播放器播放时状态转换

IjkMediaPlayer 成员函数:mp_state_,表示播放状态

播放

ijkmp_create
ijkmp_set_data_source
ijkmp_prepare_async
然后等待消息MP_STATE_PREPARED再调⽤ijkmp_start启动播放。

停止

先调⽤ijkmp_stop
再调⽤ijkmp_destroy (ijkplayer⾥⾯是通过release调⽤destro

ijkmediaPlay

成员变量
std::mutex mutex_;
    // 真正的播放器
    FFPlayer *ffplayer_ = NULL;
    //函数指针, 指向创建的message_loop,即消息循环函数
    //    int (*msg_loop)(void*);
    std::function<int(void *)> msg_loop_ = NULL; // ui处理消息的循环
    //消息机制线程
    std::thread *msg_thread_; // 执行msg_loop
    //    SDL_Thread _msg_thread;
    //字符串,就是一个播放url
    char *data_source_;
    //播放器状态,例如prepared,resumed,error,completed等
    int mp_state_;  // 播放状态
成员函数
  • ijkmp_create
    创建IjkMediaPlayer
    创建FFPlayer(ffplay.c)
    保存ui传⼊的回调msg_loop函数
    初始化mutex
    最终如果失败则调⽤destroy_p
int IjkMediaPlayer::ijkmp_create(std::function<int (void *)> msg_loop)
{
    int ret = 0;
    ffplayer_= new FFPlayer();
    if(!ffplayer_) {
        std::cout << " new FFPlayer() failed\n ";
        return -1;
    }
    // msg_loop_ 函数指针
    msg_loop_ = msg_loop;

    ret = ffplayer_->ffp_create();

    if(ret < 0) {
        return -1;
    }
    return 0;
}
  • ijkmp_destroy
    停⽌msg_loop线程
    释放mutex
    释放自己delete this

int IjkMediaPlayer::ijkmp_destroy()
{
    ffplayer_->ffp_destroy();
    return 0;
}
  • ijkmp_prepare_async
    状态设置为MP_STATE_ASYNC_PREPARING(正在准备)
    启动消息队列msg_queue_start
    调用FFplayer的prepare_async_l
int IjkMediaPlayer::ijkmp_prepare_async()
{
    // 判断mp的状态
    // 正在准备中
    mp_state_ = MP_STATE_ASYNC_PREPARING;

    // 启用消息队列
    msg_queue_start(&ffplayer_->msg_queue_);
    // 创建循环线程
    msg_thread_ = new std::thread(&IjkMediaPlayer::ijkmp_msg_loop, this, this);
    // 调用ffplayer
    int ret = ffplayer_->ffp_prepare_async_l(data_source_);
    if(ret < 0) {
        mp_state_ = MP_STATE_ERROR;
        return -1;
    }
    return 0;
}
  • ijkmp_start
    先检测当前的状态是否可以转为start,删除队列⾥的FFP_REQ_START消息,删除队列⾥的FFP_REQ_PAUSE消息
    发送FFP_REQ_START消息,jkMediaPlayer的循环⾥,ijkmp_get_msg处理FFP_REQ_START,然后调⽤ffp_start_l触发播放
int IjkMediaPlayer::ijkmp_start()
{
     ffp_notify_msg1(ffplayer_, FFP_REQ_START);
}
  • ijkmp_stop
    先检测当前的状态是否可以执⾏stop,⽐如MP_STATE_IDLE状态就没有必要调⽤stop,删除队列⾥的FFP_REQ_START/PAUSE消息
    调⽤FFPlayer的ffp_stop_l,先请求abort_request = 1,然后暂停输出toggle_pause

int IjkMediaPlayer::ijkmp_stop()
{
    int retval = ffplayer_->ffp_stop_l();
    if (retval < 0) {
        return retval;
    }
}

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

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

相关文章

SpringMVC--02--上下文工具类(RequestContextHolder)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 RequestContextHolder背景1.RequestContextHolder的使用2.request和response怎么和当前请求挂钩?3.request和response等是什么时候设置进去的? 案例应用---用户信…

【C++题解】1027 - 求任意三位数各个数位上数字的和

问题&#xff1a;1027 - 求任意三位数各个数位上数字的和 类型&#xff1a;基础问题 题目描述&#xff1a; 对于一个任意的三位自然数 x &#xff0c;编程计算其各个数位上的数字之和 S 。 输入&#xff1a; 输入一行&#xff0c;只有一个整数 x(100≤x≤999) 。 输出&…

微信小程序 uniapp+vue城市公交线路查询系统dtjl3

小程序Android端运行软件 微信开发者工具/hbuiderx uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 前端&#xff1a;HTML5,CSS3 VUE 后端&#xff1a;java(springbootssm)/python(flaskdja…

STM32完成软件I2C通讯

今天的重点是利用STM32的软件方案和MPU60506轴姿态传感器建立通讯&#xff0c;今天只完成了简单的发送地址和接收应答的部分&#xff0c;特此记录一下过程&#xff0c;以后忘记可以随时翻出来看看。 先介绍最基本的I2C通讯的最基本的6个时序&#xff1a; 一&#xff1a;起始条…

goproxy 简单介绍 及一键安装脚本

goproxy 官网 https://goproxy.cn/ GoProxy 是一项用于 Go 模块的高性能代理服务&#xff0c;旨在为 Go 开发人员提供更快速、更可靠的模块下载体验。它提供以下主要功能&#xff1a; 全球分布式代理服务器: GoProxy 在全球多个地区部署了代理服务器&#xff0c;例如拉斯维加…

驱动开发:探索DRIVER_OBJECT驱动对象

本章将探索驱动程序开发的基础部分&#xff0c;了解驱动对象DRIVER_OBJECT结构体的定义&#xff0c;一般来说驱动程序DriverEntry入口处都会存在这样一个驱动对象&#xff0c;该对象内所包含的就是当前所加载驱动自身的一些详细参数&#xff0c;例如驱动大小&#xff0c;驱动标…

B站基于Apache Ranger的大数据权限服务的技术演进

01 背景 随着云计算、大数据技术的日趋成熟&#xff0c;复杂多元、规模庞大的数据所蕴含的经济价值和社会价值逐步凸显&#xff0c;数据安全也是企业面临的巨大挑战&#xff0c;B站一直致力于对用户隐私数据的保护。 02 Ranger概述 2.1 用户认证 提到安全&#xff0c;就不得不…

uni-app web端使用getUserMedia,摄像头拍照

<template><view><video id"video"></video></view> </template> 摄像头显示在video标签上 var opts {audio: false,video: true }navigator.mediaDevices.getUserMedia(opts).then((stream)> {video document.querySelec…

emmet语法--快速生成html标签

emmet语法介绍 可以直接把它理解为快捷键。 通过一定简略的缩写配合快捷键&#xff0c;直接生成我们想要的html代码。 vscode中已经内置了emmet语法&#xff0c;可以直接使用。 emmet的核心就是tab键&#xff0c;我们输入关键词然后按下tap就可以直接生成我们要的代码。 标…

高云FPGA的管脚约束文件的复制

问&#xff1a;Gowin里面能不能直接拷贝一个管脚约束文件进去用&#xff1f; 答&#xff1a; 可以直接拷贝&#xff0c;但是拷贝前后两个工程对应的芯片必须要是同一个芯片 拷贝方法: 第一步&#xff1a;按照被拷贝约束文件对应的芯片新建一个工程&#xff0c;然后将原工程文…

产品推荐 | 基于Lattice的Crosslink系列LIF-MD6000 FPGA开发板

1、产品概述 LATTICE是一家老牌的FPGA厂家。在CPLD和FPGA低成本&#xff0c;小封装独树一帜。特别在消费电子&#xff0c;小型化设备&#xff0c;控制领域用的比较多。 Crosslink开发板采用Lattice的Crosslink家族系列芯片&#xff0c;LIF-MD6000-6JM80。Crosslink芯片具有低…

取出/var/log/secure中一小时内登录失败超过三次的IP

取出/var/log/secure中一小时内登录失败超过三次的IP 前两个字段是日期&#xff0c;第三个字段是小时&#xff0c;第四个字段是IP cat /var/log/secure | sort -i | awk -F [ :] /Failed/{a[$1" "$2" "$3" "$4" "$(NF-3)]}END{for(i …

二百三十一、ClickHouse——DBeaver连接ClickHouse中时间戳字段的时区差了8小时

一、目的 在用kettle把MySQL中的数据同步到ClickHouse中&#xff0c;发现kettle里的数据显示正常、DataGrip查询ClickHouse中的数据显示正常&#xff0c;但是DBeaver中显示的ClickHosue中的时间字段晚8个小时 二、错误原因 DBeaver的数据库时区设置有问题 三、解决办法 右…

DP10RF001一款工作于200MHz~960MHz低功耗、高性能、单片集成的(G)FSK/OOK无线收发芯片

产品概述. DP10RF001是一款工作于200MHz~960MHz范围内的低功耗、高性能、单片集成的(G)FSK/OOK无线收发机芯片。内部集成完整的射频接收机、射频发射机、频率综合器、调制解调器&#xff0c;只需配备简单、低成本的外围器件就可以获得良好的收发性能。芯片支持灵活可设的数据包…

[大模型]Langchain-Chatchat安装和使用

项目地址&#xff1a; https://github.com/chatchat-space/Langchain-Chatchat 快速上手 1. 环境配置 首先&#xff0c;确保你的机器安装了 Python 3.8 - 3.11 (我们强烈推荐使用 Python3.11)。 $ python --version Python 3.11.7接着&#xff0c;创建一个虚拟环境&#xff…

Day98:云上攻防-云原生篇K8s安全Config泄漏Etcd存储Dashboard鉴权Proxy暴露

目录 云原生-K8s安全-etcd(Master-数据库)未授权访问 etcdV2版本利用 etcdV3版本利用 云原生-K8s安全-Dashboard(Master-web面板)未授权访问 云原生-K8s安全-Configfile鉴权文件泄漏 云原生-K8s安全-Kubectl Proxy不安全配置 知识点&#xff1a; 1、云原生-K8s安全-etcd未…

Failure Unable to retrieve image details-解决Portainer与Docker v26不兼容问题

文章目录 前言解决过程解决方法一解决方法二 前言 今天登上服务器习惯性的升级了yum软件包&#xff0c;结果这一更新后导致Portainer不能正常使用&#xff0c;后续进行成功解决&#xff0c;简单记录一下 解决过程 事故过程模拟 当时顺手升级下docker版本(V26.0.1) 结果Porta…

OpenHarmony南向之编译构建框架

title: OpenHarmony南向之编译构建框架 categories:- OpenHarmony tags:- Ninja- GN author: shell cover: /img/oh/build_framework_ZN.png date: 2024-01-03 21:05:38概述 OpenHarmony编译子系统是以GN和Ninja构建为基座&#xff0c;对构建和配置粒度进行部件化抽象、对内建…

智能售货机:引领便捷生活

智能售货机&#xff1a;引领便捷生活 在这个科技迅速进步的时代&#xff0c;便捷已成为生活的必需。智能售货机作为技术与便利完美结合的产物&#xff0c;正逐渐改变我们的购物方式&#xff0c;为都市生活增添新的活力。 智能售货机的主要优势是它的极致便利性。不论是在地铁…

局域网管理软件哪个好?局域网电脑管理系统实践案例

之前有一个公司案例&#xff0c;是这样的&#xff1a; 公司名称&#xff1a;智慧科技有限公司 背景&#xff1a; 智慧科技有限公司是一家拥有数百名员工的中型企业&#xff0c;随着业务的快速发展&#xff0c;公司面临着网络管理上的挑战。 员工在日常工作中需要频繁地访问…