浅析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;
}
阅读(1282) | 评论(0) | 转发(0) |