Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1416873
  • 博文数量: 1334
  • 博客积分: 645
  • 博客等级: 上士
  • 技术积分: 5762
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-25 16:56
文章分类

全部博文(1334)

文章存档

2014年(108)

2013年(1059)

2012年(169)

分类:

2012-12-07 17:02:37

浅析alsa声卡substream->runtime的hw规则rule添加函数

snd_pcm_open_substream
==> snd_pcm_hw_constraints_init(substream);
==*> snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
                   snd_pcm_hw_rule_format, NULL, 《浅析alsa声卡驱动snd_pcm_hw_rule_format函数》
                   SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
// 为该runtime追加hw硬件rules规则,来最终约束substream所属声卡支持的参数特性[luther.gliethttp]
int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
            int var,
            snd_pcm_hw_rule_func_t func, void *private,
            int dep, ...)
{
    struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
    struct snd_pcm_hw_rule *c;
    unsigned int k;
    va_list args;
    va_start(args, dep);
    if (constrs->rules_num >= constrs->rules_all) {
// 对于第1次执行,那么constrs->rules_num和constrs->rules_all都将等于0,所以这里完成扩容操作.
        struct snd_pcm_hw_rule *new;
        unsigned int new_rules = constrs->rules_all + 16;   // 一次性扩容16个rules存储单元
        new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);   // 扩容后连续存储空间申请[luther.gliethttp]
        if (!new)
            return -ENOMEM;
        if (constrs->rules) {
            memcpy(new, constrs->rules,                     // 第1次constrs->rules等于0,之后将拷贝被扩容的原始数据
                   constrs->rules_num * sizeof(*c));
            kfree(constrs->rules);                          // 之后释放先前的constrs->rules内存空间
        }
        constrs->rules = new;                               // 扩容后新申请的内存作为默认rules内存空间
        constrs->rules_all = new_rules;                     // +16后总长度[luther.gliethtttp]
    }
    c = &constrs->rules[constrs->rules_num];                // constrs->rules_num将从0,1,2,....开始依次递增.
    c->cond = cond;                                         // 0
    c->func = func;                                         // snd_pcm_hw_rule_format -- 对var类型变量的回调处理函数
    c->var = var;                                           // SNDRV_PCM_HW_PARAM_FORMAT -- var变量
    c->private = private;                                   // NULL
    k = 0;
    while (1) {
        if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps)))
            return -EINVAL;
        c->deps[k++] = dep;                                 // SNDRV_PCM_HW_PARAM_SAMPLE_BITS -- 依赖规则
        if (dep < 0)                                        // 以-1作为dep依赖量的结尾.
            break;
        dep = va_arg(args, int);
    }
    constrs->rules_num++;                                   // 递增rules_num总数
    va_end(args);
    return 0;
}

阅读(583) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~