news 2026/5/2 21:55:24

Android tinyalsa之pcm_close调用流程与实战(一百零四)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android tinyalsa之pcm_close调用流程与实战(一百零四)

简介:CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列原创干货持续更新中……】🚀
Android多媒体专栏地址:多媒体系统工程师系列原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课🚀
专题四:Android15快速自定义与集成音效实战课🚀
专题五:Android15音频策略实战课🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例)🚀

人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮


🍉🍉🍉文章目录🍉🍉🍉

      • 🌻1. 前言
      • 🌻2. 用法与应用场景
      • 🌻3. 调用流程剖析
        • 3.1 核心步骤
        • 3.2 涉及核心时序图
      • 🌻4. 实战应用案例
      • 🌻5. 用法总结

🌻1. 前言

本篇目的:Android tinyalsa之pcm_close调用流程与实战。

🌻2. 用法与应用场景

pcm_closetinyalsa库中用于关闭 PCM 设备并释放所有相关资源的终点函数。它不仅负责用户态内存的回收,更重要的是触发内核驱动释放物理硬件资源。

  • 用法int pcm_close(struct pcm *pcm);
  • 返回值:成功返回0。若传入指针无效,函数会安全返回。
  • 应用场景
  1. 结束音频会话:在播放或录音任务完成后,正常关闭设备节点。
  2. 错误处理路径:当pcm_open成功但后续的pcm_prepare或数据读写发生严重错误时,必须调用此函数进行资源清理。
  3. 动态路由切换:在 Android 系统切换音频路径(如 Speaker 切换至有线耳机)时,HAL 层通常需要关闭当前的 PCM 实例并重新配置。

🌻3. 调用流程剖析

3.1 核心步骤
  1. 指针合法性校验:检查传入的pcm是否为NULL或指向bad_pcmtinyalsa的设计确保了对非法句柄调用 close 也不会导致系统崩溃。
  2. 停止流传输:如果设备仍处于RUNNING状态,底层驱动会在关闭文件描述符前尝试停止 DMA 传输。
  3. 解映射 MMAP 缓冲区:检查pcm->mmap_buffer。如果用户以PCM_MMAP模式打开设备,pcm_close会自动调用munmap释放映射的内存块。
  4. 触发内核 Release:执行系统调用close(pcm->fd)。这会进入内核 ALSA 核心层,调用驱动的release回调函数,进而关闭硬件功放或重置硬件寄存器。
  5. 内存释放:调用free(pcm)销毁用户态的结构体实例,完成最后的清理工作。

关键技术:坏句柄安全回收
tinyalsapcm_open失败时也会返回一个结构体(fd 为 -1)。pcm_close能够识别这种“坏句柄”并仅释放内存而不尝试执行内核关闭操作,这简化了 HAL 层的异常处理逻辑。

3.2 涉及核心时序图
Audio Codec/DMAKernel ALSA CoreVFS (close syscall)tinyalsa (pcm_close)Audio HALAudio Codec/DMAKernel ALSA CoreVFS (close syscall)tinyalsa (pcm_close)Audio HALalt[MMAP 模式已启用]调用 pcm_close(pcm)1. 验证 pcm 指针及状态2. munmap(pcm->>mmap_buffer)3. close(pcm->>fd)触发 snd_pcm_release停止 DMA, 降低功耗硬件已重置返回4. free(pcm) 释放结构体返回 0

🌻4. 实战应用案例

此 Demo 展示了在 Android HAL 开发中,如何规范地使用pcm_close并通过指针置空防止野指针异常。

#include<tinyalsa/asoundlib.h>#include<stdio.h>#include<stdlib.h>/** * 模拟 HAL 层安全释放音频流的逻辑 */voidhal_pcm_release(structpcm**pp_pcm){if(pp_pcm==NULL||*pp_pcm==NULL){return;}/* 1. 执行 tinyalsa 关闭操作 */printf("HAL: Closing pcm device...\n");intret=pcm_close(*pp_pcm);if(ret!=0){printf("HAL: Warning - pcm_close returned error code %d\n",ret);}/* 2. 极其重要:手动将原指针置为 NULL * 防止 HAL 层其他线程误用已释放的内存 (Use-After-Free) */*pp_pcm=NULL;printf("HAL: Resource cleanup complete.\n");}intmain(){structpcm_configconfig={.channels=2,.rate=44100,.period_size=1024,.period_count=4,.format=PCM_FORMAT_S16_LE};// 打开设备 (声卡 0, 设备 0, 播放模式)structpcm*out_stream=pcm_open(0,0,PCM_OUT,&config);if(out_stream&&pcm_is_ready(out_stream)){printf("HAL: Audio session started.\n");// ... 此处执行音频数据写入 pcm_write ...}// 无论打开成功还是失败,最终都要调用清理函数hal_pcm_release(&out_stream);return0;}

🌻5. 用法总结

特性详情描述
内存管理完全清理。内部集成了对mmap缓冲区和pcm结构体本身的free
调用配对必须与 pcm_open 配对。漏掉 close 会导致声卡被占用(Device Busy)以及系统 fd 泄露。
线程安全非线程安全。严禁在主线程 close 的同时在另一线程执行pcm_write,需在 HAL 层加锁。
硬件状态重置硬件。该函数执行后,内核通常会关闭相关的 DAC/ADC 电源以节省功耗。
容错性高容忍度。可以安全处理未成功 ready 的 pcm 指针,不会造成内核异常。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 17:56:37

Z-Image-Turbo让非技术人员也能玩转AI绘画

Z-Image-Turbo让非技术人员也能玩转AI绘画 你有没有过这样的经历&#xff1a;想为朋友圈配一张定制插画&#xff0c;想给公司产品设计一张海报&#xff0c;或者只是单纯想把脑海里那个“穿汉服站在樱花雨中的少女”变成现实——但打开Stable Diffusion&#xff0c;面对一堆参数…

作者头像 李华
网站建设 2026/4/25 21:50:00

Kook Zimage 真实幻想 Turbo:5分钟快速上手梦幻风格AI绘画

Kook Zimage 真实幻想 Turbo&#xff1a;5分钟快速上手梦幻风格AI绘画 1. 为什么你值得花5分钟试试这个“幻想引擎” 你有没有过这样的时刻&#xff1a;脑子里浮现出一个画面——月光下的银发少女站在浮空花园里&#xff0c;裙摆飘动&#xff0c;身后是半透明的水晶蝶翼&…

作者头像 李华
网站建设 2026/5/1 21:28:47

BSHM镜像深度体验:人像抠图的正确打开方式

BSHM镜像深度体验&#xff1a;人像抠图的正确打开方式 人像抠图这件事&#xff0c;听起来简单&#xff0c;做起来却常让人抓狂——边缘毛躁、发丝丢失、半透明区域糊成一片。你是不是也经历过&#xff1a;花半小时调参数&#xff0c;结果换背景后头发像被水泡过&#xff1f;或…

作者头像 李华