static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t frames, frames1;
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
if (runtime->oss.plugin_first) {
// 如果存在plugin音频转换插件
struct snd_pcm_plugin_channel *channels;
size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; // oss_frame_bytes为所有声道一次全采样所占用存储空间字节数[luther.gliethttp]
if (!in_kernel) {
// 如果buf数据来自user用户空间,那么调用copy_from_user拷贝数据[luther.gliethttp]
// 否则音频数据已经放到了runtime->oss.buffer缓冲区中.
if (copy_from_user(runtime->oss.buffer, (const char __user *)buf, bytes))
return -EFAULT;
buf = runtime->oss.buffer;
}
frames = bytes / oss_frame_bytes; // bytes一共包含多少个采样样点数[luther.gliethttp]
frames1 = snd_pcm_plug_client_channels_buf(substream, (char *)buf, frames, &channels);
if (frames1 < 0)
return frames1;
// 向该substream->runtime->oss.plugin_first链表上包含的所有plugin音频转换插件传输本数据[luther.gliethttp]
frames1 = snd_pcm_plug_write_transfer(substream, channels, frames1);
if (frames1 <= 0)
return frames1;
bytes = frames1 * oss_frame_bytes; // 本次传输数据长度
} else
#endif
{
// ok, 不存在plugin音频转换插件
frames = bytes_to_frames(runtime, bytes); // bytes一共包含多少个采样样点数[luther.gliethttp]
frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel);
《浅析alsa声卡驱动snd_pcm_oss_write3函数》 if (frames1 <= 0)
return frames1;
bytes = frames_to_bytes(runtime, frames1); // 本次传输数据长度
}
return bytes;
}
阅读(1032) | 评论(0) | 转发(0) |