1. 程式人生 > >Android中AudioFlinger:將AudioTrack從一個device切到另一個device輸出的實現邏輯

Android中AudioFlinger:將AudioTrack從一個device切到另一個device輸出的實現邏輯

目前在調查AudioFlinger,想做到從一個裝置輸出到輸出到兩個裝置的轉換。面臨以下問題:

1,  某個thread如何改變某個playback執行緒的輸出route.

根據調查的結果,這個route只支援在同一個裝置上的切換,比如在primary裝置內部切換路由DAC0切到DAC1等等。不支援多個裝置間的路由的切換。

2,  當thread路由變化後,如何將已經加入的track從一個執行緒移動到另一個執行緒

關於這塊,我從程式碼中無法看出是啥時候做了這件事,但是經過測試後,發現其還真是支援track的移動。所以就掛上gdbserver來檢視。列印的backtrace如下:

(gdb) break /home/wqw/Projects/KM500/frameworks/av/services/audioflinger/AudioFlinger.cpp:461

Breakpoint 1 at 0x4007fe36: file frameworks/av/services/audioflinger/AudioFlinger.cpp, line 461.

(gdb) c

Continuing.

[New Thread 3411]

[Switching to Thread 3411]

Breakpoint 1, android::AudioFlinger::createTrack (this=0x40f4a078, pid=2234, streamType=AUDIO_STREAM_MIX, sampleRate=48000,

    format=AUDIO_FORMAT_PCM_16_BIT, channelMask=3, frameCount=3343, flags=0, sharedBuffer=..., output=6, tid=-1, sessionId=0x41439d3c,

    status=0x43d95cf8) at frameworks/av/services/audioflinger/AudioFlinger.cpp:469

469             if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {

(gdb) bt

#0  android::AudioFlinger::createTrack (this=0x40f4a078, pid=2234, streamType=AUDIO_STREAM_MIX, sampleRate=48000,

    format=AUDIO_FORMAT_PCM_16_BIT, channelMask=3, frameCount=3343, flags=0, sharedBuffer=..., output=6, tid=-1, sessionId=0x41439d3c,

    status=0x43d95cf8) at frameworks/av/services/audioflinger/AudioFlinger.cpp:469

#1  0x4025e502 in android::AudioTrack::createTrack_l (this=0x41439cc8, streamType=AUDIO_STREAM_MIX, sampleRate=48000,

    format=AUDIO_FORMAT_PCM_16_BIT, channelMask=3, frameCount=<optimized out>, flags=AUDIO_OUTPUT_FLAG_NONE, sharedBuffer=..., output=6)

    at frameworks/av/media/libmedia/AudioTrack.cpp:899

#2  0x4025e71e in android::AudioTrack::restoreTrack_l (this=0x41439cc8, [email protected], fromStart=<optimized out>)

    at frameworks/av/media/libmedia/AudioTrack.cpp:1364

#3  0x4025ea9c in android::AudioTrack::obtainBuffer (this=0x41439cc8, audioBuffer=0x43d95df0, waitCount=-1)

    at frameworks/av/media/libmedia/AudioTrack.cpp:1015

#4  0x4025f360 in android::AudioTrack::write (this=0x41439cc8, buffer=<optimized out>, userSize=3340)

    at frameworks/av/media/libmedia/AudioTrack.cpp:1116

#5  0x405d37a4 in android::MediaPlayerService::AudioOutput::write (this=0x400dcc68, buffer=<optimized out>, size=<optimized out>)

    at frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp:1665

#6  0x413696d2 in android::AndroidAudioRender::WriteDevice (this=0x411a69f8,

    pBuffer=0x413ef5a4 "\320\016A\377\031\a\367\375\261\377j\374J\374\345\371\372\375\234\370S", nActuralLen=3340)

    at external/fsl_imx_omx/OpenMAXIL/src/component/android_audio_render/AndroidAudioRender.cpp:374

#7  0x411e29a2 in AudioRender::RenderPeriod (this=0x411a69f8) at external/fsl_imx_omx/OpenMAXIL/src/component/common/AudioRender.cpp:667

#8  0x411e2f6a in RenderData (this=0x411a69f8) at external/fsl_imx_omx/OpenMAXIL/src/component/common/AudioRender.cpp:634

#9  AudioRender::RenderData (this=0x411a69f8) at external/fsl_imx_omx/OpenMAXIL/src/component/common/AudioRender.cpp:624

#10 0x411e33c4 in AudioRender::ProcessDataBuffer (this=0x411a69f8)

    at external/fsl_imx_omx/OpenMAXIL/src/component/common/AudioRender.cpp:318

#11 0x411dbc22 in ProcessBuffer (this=0x41316030) at external/fsl_imx_omx/OpenMAXIL/src/component/common/ExecutingState.cpp:48

#12 ExecutingState::ProcessBuffer (this=0x41316030) at external/fsl_imx_omx/OpenMAXIL/src/component/common/ExecutingState.cpp:42

#13 0x411db7a4 in DoThread (arg=0x411a69f8) at external/fsl_imx_omx/OpenMAXIL/src/component/common/ComponentBase.cpp:570

#14 0x400eb3fc in __thread_entry (func=0x411db749 <DoThread(void*)>, arg=0x411a69f8, tls=0x43d95f00) at bionic/libc/bionic/pthread.c:204

#15 0x400eaae8 in pthread_create (thread_out=0x43d95f00, attr=0x4011f1e0, start_routine=0x411db749 <DoThread(void*)>, arg=<optimized out>)

at bionic/libc/bionic/pthread.c:348

其基本的流程是: MediaPlayer呼叫AudioTrackwrite函式à呼叫obtain buffer獲取可寫記憶體à發現TRACKFLAG設為CBLK_INVALID_ON後,變會呼叫

restoreTrack_l-à restoreTrack_l內部會呼叫AudioFlinger::createTrack建立一個新的,並放到合適的thread中。

另外,這個FLAG是在改變路由時,將這些不符合條件的track打上CBLK_INVALID_ON的標識的,log如下:

D/AudioPolicyManagerBase( 2234): checkAndSetVolume() cannot set stream 6 volume with force use = 0 for comm

D/qwang   ( 2234): setStreamOutput() stream 10 to output 6

D/qwang   ( 2234): MixerThread::invalidateTracks() mixer 0x40f4d330, streamType 10, mTracks.size 0

D/qwang   ( 2234): MixerThread::invalidateTracks() mixer 0x40f2a008, streamType 10, mTracks.size 3

D/qwang   ( 2234): MixerThread::invalidateTracks() mixer 0x4134a008, streamType 10, mTracks.size 1

D/qwang   ( 2234): MixerThread::invalidateTracks() mixer 0x41791008, streamType 10, mTracks.size 1

相關推薦

AndroidAudioFlingerAudioTrack一個device一個device輸出實現邏輯

目前在調查AudioFlinger,想做到從一個裝置輸出到輸出到兩個裝置的轉換。面臨以下問題: 1,  某個thread如何改變某個playback執行緒的輸出route. 根據調查的結果,這個route只支援在同一個裝置上的切換,比如在primary裝置內部切換路由,

C# 委託的應用1方法作為引數傳遞給一個方法

     長期以來,c和c++的程式設計師利用方法指標,將方法作為引數傳給另一個方法。c#使用委託來提供相同的功能,它將方法作為物件封裝起來,允許在執行時間接地繫結一個方法呼叫。      下面將通過氣泡排序的例子講解委託的產生     示例1 :該方法對一個整數陣列執行升

原理上理解如何由震源機制一個節面的解strike,dip,rake可以求出一個節面的解

方向 矢量 不難 角度 image 技術 log 表達 分享 首先,需要回到最原始的地震矩的表達式: 已知strike,dip,rake 根據strike和dip可以求出v,根據strike,dip,rake,可以求出u。 把求出來的v和u互換,相當於原來的位錯矢量變成法

androidcanvas.drawText參數的介紹以及繪制一個文本居中的案例

.cn 介紹 ondraw image 圖片 oat sin es2017 tco float baseline = height/2 + mPaint.getTextSize()/2 - mPaint.getFontMetrics().descent;文字尺寸就是 pr

NodeJS資料夾按照存放路徑變成一個對應的JSON

在程式設計之前,一定要有一個信條:程式碼是為了減少工作量而生的,重複枯燥的工作是不能容忍的。 需求 這是由上篇文章衍生出的需求,我已經將一個資料夾內所有的檔名轉譯為英文,但我在頁面上還需要將這些圖片引入載入。如果一個一個手寫到程式裡,未免有點勞心勞神。那麼何不將這個資料夾按照存放路徑變成一個相應的JSON

Android一個Activty控制一個Activity的函式及變數

在Android中,有時候我們需要在當前的Activity結束掉堆疊中其他的Activity,比如:Activity A,B,C,D 在堆疊中的順序如下:  A->B->C->D,假如我們現在處於Activity D,我們想在D中呼叫A或B或C的finish()函式,或者

Spring Batch資料Web服務處理到MongoDB

概觀 在這篇文章中,我們將介紹如何建立一個使用Web服務資料並將其插入MongoDB資料庫的Spring Batch應用程式。 要求 閱讀本文的開發人員必須熟悉Spring Batch(示例)和MongoDB。 環境 Mongo資料庫部署在MLab中。請按照本快速入門中的步驟操作。 批

其他庫的表的資料批量插入新增到一個庫的表

jkdb.factory中的jkdb為資料庫,factory為表名 兩張表的欄位和欄位型別需要一致。 INSERT INTO jkdb.factory SELECT id, name, sex

Android 一個activity到一個activity(有傳送資料)

Intent activity_change= new Intent(Activityanother.this, MainActivity.class); //切換 Activityanot

android 利用cmdline,引數preloader傳遞到kernel [MTK通用]

以定義引數 cus_param 為例,int型變數。 1. Preloader部分 Platform.h(mediatek\platform\[$platform]\preloader\src\drivers\inc\platform.h) 在如下結構體中加cus_para

如何url作為一個引數放到一個url

在開發中可能會遇到要將一個url作為一個引數來傳遞,那麼怎麼做呢,你可以通過encodeURIComponent()函式來實現,下面就看一些使用例項。  “http://localhost/servlet?ref="+encodeURIComponent('http://l

Oracle面試題如何把一個一個schema到一個schema?

問題來源:http://www.jobui.com/mianshiti/it/oracle/4134/ 實現把一個表從一個schema到另一個schema有幾種可能的方法: 1. export – import :http://blog.itpub.net/20553601

如何用java讀取csv檔案指定行列的資料,並csv資料元素隨機置零後儲存到一個csv檔案

這個流程可以大致分為兩步驟:1.讀取csv檔案中的資料2.生成隨機數,將csv的資料隨機置零,將新生成的檔案儲存到新的csv中一、首先我們進行第一步:讀取csv中的檔案:讀取函式格式為public static double readin(int row,int col)

Android 一個Activity呼叫一個Activity的公有方法

問題描述: Activity A A中有一個TextView控制元件  ,一個Button控制元件,點選Button控制元件啟用Activity  B,還有一個公有方法c ,c 傳入一個String引數s 將s 顯示到TextView上 Activity B 一個EditV

Android一個Fragment呼叫一個fragment的方法

先看需求,是要實現上圖中篩選功能。父級(“發現”頁面)已經是Fragment,子級“推薦”和“附近”也是Fragment;於是就相當於從一個fragment去動態控制另一個fragment;在苦惱並查閱了一些資料後並沒有找到好的解決方案,最後看到百度知道有人提到這個問題

SQL如何一個的某一列的資料複製到一個的某一列裡

表一: SPRD PRD_NO      SPC          001                NULL 002               NULL 003               NULL ...                    ... 表二

利用Qt Creator 如何在ROS 專案一個介面呼叫一個介面?

首先介紹我使用的是Qt Creator 4.4.1,Based on Qt 5.9.1 (GCC 4.9.4, 64 bit),為了方便在qt中開發ROS介面,安裝了ros_qtc_plugin 外掛(

Android進階二、源碼角度看透 HandlerThread 和 IntentService

pri vat thread err 應該 red service adp 結束 上篇文章我們講日誌的存儲策略的時候用到了HandlerThread,它適合處理“多而小的任務”的耗時任務的時候,避免產生太多線程影響性能,那這個HandlerThread的原理到底是怎樣的呢?

perl怎麽拷貝一個文件到一個文件夾或者怎麽拷貝文件夾到一個文件夾

不存在 程序 bold 拷貝文件 color 函數 str del 文件夾 File::Copy 主要提供了copy和move函數#!/usr/bin/perluse strict; use warnings; use File::Copy; my $filein=$AR

POJ 3126 Prime Path【一個素數變為一個素數的最少步數/BFS】

lan mem 奇數 offices ring finance primes iostream int Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26475 Accepted: