应用层设置option如何让底层使用

本文介绍如何通过应用层设置MP4 DRM头密钥,并将其传递至底层以供使用。主要内容包括:在avformat.h中增加字段,在options_table.h中定义选项,应用层调用setOption方法,以及底层初始化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

应用层调用 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, “_mp4_drm_head_key”, mSDKSettings.getMp4DrmHeadKey());

使用步骤:

1.option_table.h中添加字段,avformat.h文件的AVFormatContext结构体中增加字段

avformat.h
typedef struct AVFormatContext {
    int _mp4_drm_head_key;  // 增加头部的字段
}

options_table.h android\contrib\ffmpeg-armv7a\libavformat   
static const AVOption avformat_options[] = {
    {"_mp4_drm_head_key", "����mp4�ӽ��ܵ�head key", OFFSET(_mp4_drm_head_key), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D},
}

2.应用层调用setOption相应的字符串的key

应用层调用:
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "_mp4_drm_head_key", mSDKSettings.getMp4DrmHeadKey());
底层设置过程:
IjkMediaPlayer_setOption
    ijkmp_set_option
        void ffp_set_option(FFPlayer *ffp, int opt_category, const char *name, const char *value)
        {
            if (!ffp)
                return;

            AVDictionary **dict = ffp_get_opt_dict(ffp, opt_category);
            av_dict_set(dict, name, value, 0);
        }

            static AVDictionary **ffp_get_opt_dict(FFPlayer *ffp, int opt_category)
            {               
                switch (opt_category) {
                    case FFP_OPT_CATEGORY_FORMAT:   return &ffp->format_opts;   // 设置到FFPlayer的字典中
                    case FFP_OPT_CATEGORY_CODEC:    return &ffp->codec_opts;
                    case FFP_OPT_CATEGORY_SWS:      return &ffp->sws_dict;
                    case FFP_OPT_CATEGORY_PLAYER:   return &ffp->player_opts;
                    case FFP_OPT_CATEGORY_SWR:      return &ffp->swr_opts;
                }
            }

3.底层初始化的时候自动赋值:设置字典中的数据到AVFormatContext结构中对应的 成员变量中

IjkMediaPlayer_prepareAsync 10  ijkplayer_jni.c (ijkmedia\ijkplayer\android)
    ijkmp_prepare_async     ijkplayer.h (ijkmedia\ijkplayer)
        ijkmp_prepare_async_l   25  ijkplayer.c (ijkmedia\ijkplayer)
            ffp_prepare_async_l 12  ff_ffplay.c (ijkmedia\ijkplayer)
                stream_open 42  ff_ffplay.c (ijkmedia\ijkplayer)
                    avformat_open_input 77  utils.c (android\ffmpeg-armv7a\libavformat)

                    stream_open中调用:avformat_open_input(&ic, is->filename, is->iformat, &ffp->format_opts);
                    // 打开输入
                    int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
                    {
                        AVFormatContext *s = *ps;
                        int ret = 0;
                        AVDictionary *tmp = NULL;

                        if (!s && !(s = avformat_alloc_context()))
                            return AVERROR(ENOMEM);                 

                        if (fmt)
                            s->iformat = fmt;

                        // 将所有option拷贝到临时的options中
                        if (options)
                            av_dict_copy(&tmp, *options, 0);

                        // 将先前的option设置到AVFormatContext的相应的成员变量中
                        if ((ret = av_opt_set_dict(s, &tmp)) < 0)
                            goto fail;

                        // 初始化输入
                        if ((ret = init_input(s, filename, &tmp)) < 0)
                            goto fail;
                    }

4.底层可使用应用层设置进来的数据

AVFormatContext结构中对应的成员变量值已经由字典的值设置进来了

总结下:

1.底层需要应用层设置数据(初始化)
    底层的AVFormatContext结构增加对应的成员变量并将相应的成员变量的说明设置到table中
2.应用层调用setOption设置相应的数据(设置)
3.应用层设置数据到底层,底层走“## 3.底层初始化的时候自动赋值”流程,自动赋值给AVFormatContext结构(自动赋值)
4.底层相应的代码可以使用到设置进来的数据(使用数据)
### 如何正确使用 QTableView 在 Qt 中 #### 创建并初始化 QTableView 实例 为了创建 `QTableView` 并将其集成到应用程序中,通常需要先实例化这个类的对象。由于 `QTableView` 继承自 `QAbstractItemView`[^1],因此它能够利用基类提供的接口来展示由模型管理的数据。 ```cpp // 初始化 QTableView 对象 QTableView *tableView = new QTableView(parent); ``` #### 设置数据源模型 为了让表格视图显示有用的信息,必须为其指定一个实现了 `QAbstractItemModel` 接口的具体子类作为其背后的数据存储器。这一步骤通过调用 `setModel()` 方法完成: ```cpp // 假设 model 是已经准备好的数据模型对象 tableView->setModel(model); ``` #### 启用排序功能 如果希望允许用户点击列头来进行升序或降序排列的话,则只需启用内置的排序支持即可。此操作非常简便,仅需一行代码就能开启这一特性[^3]。 ```cpp tableView->setSortingEnabled(true); ``` #### 添加多选按钮(复选框) 当需求涉及到每行记录前放置一个多选框供用户勾选时,可以通过定制化的委托机制达成目标。具体来说,应该派生出自定义版本的 `QStyledItemDelegate` 类型,并重写相应的方法以便适当地渲染以及处理交互逻辑[^2]。 ```cpp class CheckBoxDelegate : public QStyledItemDelegate { void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; // 应用自定义委托给特定列 tableView->setItemDelegateForColumn(columnIndex, new CheckBoxDelegate()); ``` #### 处理输入验证与回滚错误修改 为了避免非法数值被提交至底层数据库或其他持久层组件,在检测到不符合预期范围内的更改之后应当立即恢复原始状态并向用户提供反馈提示信息。对于这种情况下的解决方案之一就是在编辑结束事件发生之时检查新值的有效性;如果不满足条件就拒绝更新并且重新加载先前存在的内容[^5]。 ```cpp void TableView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint){ QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor); if (lineEdit && !validateInput(lineEdit->text())) { // 显示警告对话框告知用户存在问题 QMessageBox::warning(this,"Error","Invalid input"); // 取消本次变更并将焦点返回原处等待修正 lineEdit->setText(originalValue); editor->setFocus(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值