इस लेख में, Android ऑडियो को डीबग करने के लिए कुछ सलाह और तरकीबें दी गई हैं.
टी सिंक
"टी सिंक", ऑडियो फ़्लिंगर की डीबगिंग की सुविधा है. यह सिर्फ़ कस्टम बिल्ड में उपलब्ध है. इसका इस्तेमाल, हाल ही के ऑडियो के छोटे से हिस्से को सेव करने के लिए किया जाता है, ताकि बाद में उसका विश्लेषण किया जा सके. इसकी मदद से, असल में चलाए गए या रिकॉर्ड किए गए वीडियो की तुलना, उम्मीद के मुताबिक चलाए गए या रिकॉर्ड किए गए वीडियो से की जा सकती है.
निजता बनाए रखने के लिए, टी सिंक को डिफ़ॉल्ट रूप से बंद किया जाता है. यह कंपाइल करने के समय और रन टाइम, दोनों पर बंद होता है. टी सिंक का इस्तेमाल करने के लिए, आपको इसे फिर से कंपाइल करके चालू करना होगा. साथ ही, एक प्रॉपर्टी भी सेट करनी होगी. डीबग करने के बाद, इस सुविधा को बंद करना न भूलें. प्रोडक्शन बिल्ड में टी सिंक को चालू नहीं छोड़ा जाना चाहिए.
इस सेक्शन में दिए गए निर्देश, Android 7.x और उसके बाद के वर्शन के लिए हैं. Android
5.x और 6.x के लिए, /data/misc/audioserver
को
/data/misc/media
से बदलें. इसके अलावा, आपको userdebug या
eng बिल्ड का इस्तेमाल करना होगा. अगर userdebug बिल्ड का इस्तेमाल किया जाता है, तो पुष्टि करने की सुविधा को इन निर्देशों का इस्तेमाल करके बंद करें:
adb root && adb disable-verity && adb reboot
कंपाइल के समय सेटअप
cd frameworks/av/services/audioflinger
Configuration.h
में बदलाव करें.#define TEE_SINK
से टिप्पणी हटाएं.libaudioflinger.so
को फिर से बनाएं.adb root
adb remount
- नए
libaudioflinger.so
को डिवाइस के/system/lib
पर पुश या सिंक करें.
रन-टाइम सेटअप
adb shell getprop | grep ro.debuggable
पुष्टि करें कि आउटपुट:[ro.debuggable]: [1]
adb shell
ls -ld /data/misc/audioserver
पुष्टि करें कि आउटपुट:
drwx------ media media ... media
अगर डायरेक्ट्री मौजूद नहीं है, तो उसे इस तरह बनाएं:
mkdir /data/misc/audioserver
chown media:media /data/misc/audioserver
echo af.tee=# > /data/local.prop
यहांaf.tee
वैल्यू, नीचे बताई गई संख्या है.chmod 644 /data/local.prop
reboot
af.tee प्रॉपर्टी की वैल्यू
af.tee
की वैल्यू 0 से 7 के बीच की कोई संख्या होती है. यह वैल्यू, हर सुविधा के लिए एक बिट के हिसाब से कई बिट का जोड़ होती है.
हर बिट के बारे में कम शब्दों में जानकारी पाने के लिए, AudioFlinger.cpp
में AudioFlinger::AudioFlinger()
पर मौजूद कोड देखें:
- 1 = इनपुट
- 2 = FastMixer आउटपुट
- 4 = हर ट्रैक के लिए AudioRecord और AudioTrack
फ़िलहाल, डीप बफ़र या सामान्य मिक्सर के लिए कोई बिट नहीं है. हालांकि, "4" का इस्तेमाल करके मिलते-जुलते नतीजे मिल सकते हैं.
डेटा की जांच करना और उसे हासिल करना
- ऑडियो की जांच करें.
adb shell dumpsys media.audio_flinger
dumpsys
आउटपुट में ऐसी लाइन ढूंढें:
tee copied to /data/misc/audioserver/20131010101147_2.wav
यह एक PCM .wav फ़ाइल है.- इसके बाद,
adb pull
अपनी पसंद की/data/misc/audioserver/*.wav
फ़ाइलें चुनें; ध्यान दें कि ट्रैक के हिसाब से डंप फ़ाइल के नाम,dumpsys
आउटपुट में नहीं दिखते, लेकिन ट्रैक बंद होने पर, वे अब भी/data/misc/audioserver
में सेव रहती हैं. - दूसरों के साथ शेयर करने से पहले, निजता से जुड़ी समस्याओं के लिए डंप फ़ाइलों की समीक्षा करें.
सुझाव
ज़्यादा काम के नतीजे पाने के लिए, इन आइडिया को आज़माएं:
- टेस्ट के आउटपुट में रुकावटों को कम करने के लिए, टच की आवाज़ और बटन के क्लिक की आवाज़ बंद करें.
- सभी वॉल्यूम को बढ़ाएं.
- अगर आपको जांच के लिए किसी ऐप्लिकेशन की ज़रूरत नहीं है, तो उसे बंद कर दें.
- ट्रैक के हिसाब से डंप सिर्फ़ तब सेव किए जाते हैं, जब ट्रैक बंद हो; किसी ऐप्लिकेशन के ट्रैक के हिसाब से डेटा डंप करने के लिए, आपको उसे जबरन बंद करना पड़ सकता है
- जांच के तुरंत बाद
dumpsys
करें; रिकॉर्डिंग के लिए सीमित जगह उपलब्ध है. - डंप फ़ाइलें मिटने से बचाने के लिए, उन्हें समय-समय पर अपने होस्ट पर अपलोड करें. सिर्फ़ सीमित संख्या में डंप फ़ाइलें सेव की जाती हैं. यह सीमा पूरी होने के बाद, पुराने डंप हटा दिए जाते हैं.
वापस लाएं
जैसा कि ऊपर बताया गया है, टी सिंक की सुविधा को चालू नहीं रखा जाना चाहिए. अपने बिल्ड और डिवाइस को इस तरह से वापस लाएं:
- सोर्स कोड में किए गए बदलावों को
Configuration.h
पर वापस लाएं. libaudioflinger.so
को फिर से बनाएं.- वापस लाए गए
libaudioflinger.so
को डिवाइस के/system/lib
पर पुश या सिंक करें. adb shell
rm /data/local.prop
rm /data/misc/audioserver/*.wav
reboot
media.log
ALOGx मैक्रो
Android SDK में, स्टैंडर्ड Java भाषा का लॉगिंग एपीआई android.util.Log है.
Android NDK में, C भाषा के उस एपीआई के बारे में __android_log_print
<android/log.h>
में बताया गया है.
Android फ़्रेमवर्क के नेटिव हिस्से में, हम ALOGE
, ALOGW
,
ALOGI
, ALOGV
वगैरह नाम वाले मैक्रो का इस्तेमाल करना पसंद करते हैं. इन्हें <utils/Log.h>
में दिखाया जाता है. इस लेख में, हम इन्हें एक साथ ALOGx
के तौर पर दिखाएंगे.
इन सभी एपीआई को इस्तेमाल करना आसान है और इन्हें अच्छी तरह से समझा जा सकता है. इसलिए, ये Android प्लैटफ़ॉर्म पर हर जगह मौजूद हैं. खास तौर पर, mediaserver
प्रोसेस, जिसमें AudioFlinger साउंड सर्वर शामिल है, ALOGx
का ज़्यादा इस्तेमाल करती है.
हालांकि, ALOGx
और दोस्तों के लिए कुछ सीमाएं हैं:
-
इनमें "लॉग स्पैम" की समस्या हो सकती है: लॉग बफ़र एक शेयर किया गया संसाधन है, इसलिए इससे मिलती-जुलती लॉग एंट्री की वजह से, यह आसानी से ओवरफ़्लो हो सकता है. इस वजह से, कुछ जानकारी छूट सकती है.
ALOGV
वैरिएंट, डिफ़ॉल्ट रूप से संकलन के समय बंद होता है. हालांकि, अगर यह सुविधा चालू है, तो इससे भी लॉग स्पैम हो सकता है. -
हो सकता है कि मौजूदा कर्नेल सिस्टम कॉल ब्लॉक हो जाएं. इससे प्राथमिकता में बदलाव हो सकता है. साथ ही, मेज़रमेंट में रुकावटें आ सकती हैं और गलतियां हो सकती हैं. यह
FastMixer
औरFastCapture
जैसी समय-सीमा वाले थ्रेड के लिए खास तौर पर ज़रूरी है. - अगर लॉग स्पैम को कम करने के लिए किसी लॉग को बंद किया जाता है, तो उस लॉग से कैप्चर की गई कोई भी जानकारी मिट जाती है. किसी खास लॉग को बाद में चालू नहीं किया जा सकता. ऐसा तब किया जा सकता है, जब यह पता चल जाए कि लॉग काम का है.
NBLOG, media.log, और MediaLogService
NBLOG
एपीआई और उससे जुड़ी media.log
प्रोसेस और MediaLogService
सेवा, मीडिया के लिए एक नया लॉगिंग सिस्टम बनाती है. इसे खास तौर पर ऊपर बताई गई समस्याओं को हल करने के लिए डिज़ाइन किया गया है. हम इन तीनों के लिए, "media.log" शब्द का इस्तेमाल करेंगे. हालांकि, NBLOG
C++ लॉगिंग एपीआई है, media.log
एक Linux प्रोसेस का नाम है, और MediaLogService
लॉग की जांच करने के लिए Android बाइंडर सेवा है.
media.log
"टाइमलाइन", लॉग एंट्री की एक सीरीज़ होती है. इसमें एंट्री का क्रम सुरक्षित रहता है.
आम तौर पर, हर थ्रेड को अपनी टाइमलाइन का इस्तेमाल करना चाहिए.
फ़ायदे
media.log
सिस्टम के ये फ़ायदे हैं:
- जब तक ज़रूरत न हो, तब तक मुख्य लॉग को स्पैम नहीं करता.
mediaserver
के क्रैश होने या हैंग होने पर भी इसकी जांच की जा सकती है.- हर टाइमलाइन के हिसाब से ब्लॉक नहीं किया जाता.
- इससे परफ़ॉर्मेंस पर कम असर पड़ता है. (हालांकि, लॉगिंग का कोई भी तरीका पूरी तरह से बिना किसी रुकावट के काम नहीं करता.)
भवन निर्माण
नीचे दिए गए डायग्राम में, media.log
के आने से पहले mediaserver
प्रोसेस और init
प्रोसेस के बीच का संबंध दिखाया गया है:

पहली इमेज. media.log से पहले का आर्किटेक्चर
अहम बातें:
init
फ़ॉर्क और एक्सेक्यूटmediaserver
.init
,mediaserver
के बंद होने का पता लगाता है और ज़रूरत के हिसाब से फिर से फ़ॉर्क करता है.ALOGx
लॉगिंग नहीं दिख रही है.
नीचे दिए गए डायग्राम में, आर्किटेक्चर में media.log
को जोड़ने के बाद, कॉम्पोनेंट के नए संबंध को दिखाया गया है:

दूसरी इमेज. media.log के बाद का आर्किटेक्चर
अहम बदलाव:
-
क्लाइंट, लॉग एंट्री बनाने और उन्हें शेयर की गई मेमोरी में मौजूद सर्कुलर बफ़र में जोड़ने के लिए,
NBLOG
एपीआई का इस्तेमाल करते हैं. -
MediaLogService
, सर्कुलर बफ़र का कॉन्टेंट किसी भी समय डंप कर सकता है. -
सर्कुलर बफ़र को इस तरह से डिज़ाइन किया गया है कि शेयर की गई मेमोरी में किसी भी तरह की गड़बड़ी होने पर,
MediaLogService
क्रैश नहीं होगा. साथ ही, वह बफ़र का उतना हिस्सा डंप कर पाएगा जिस पर गड़बड़ी का असर नहीं पड़ा है. - नई एंट्री लिखने और मौजूदा एंट्री पढ़ने, दोनों के लिए सर्कुलर बफ़र, ब्लॉकिंग और लॉक-फ़्री होता है.
- सर्कुलर बफ़र में लिखने या उससे पढ़ने के लिए, कोई भी कर्नेल सिस्टम कॉल ज़रूरी नहीं है (ज़रूरी नहीं है कि टाइमस्टैंप का इस्तेमाल किया जाए).
यहां इस्तेमाल करें
Android 4.4 के बाद, AudioFlinger में सिर्फ़ कुछ लॉग पॉइंट ऐसे हैं जो media.log
सिस्टम का इस्तेमाल करते हैं. नए एपीआई, ALOGx
के जितने आसान नहीं हैं, उतने मुश्किल भी नहीं हैं.
हमारा सुझाव है कि आप लॉगिंग के नए सिस्टम को जानें, ताकि जब भी ज़रूरत पड़े, आप इसका इस्तेमाल कर सकें.
खास तौर पर, यह सुझाव AudioFlinger थ्रेड के लिए दिया जाता है, जिन्हें बार-बार, समय-समय पर, और बिना ब्लॉक किए चलाना ज़रूरी है. जैसे, FastMixer
और FastCapture
थ्रेड.
कैसे इस्तेमाल करें
लॉग जोड़ना
सबसे पहले, आपको अपने कोड में लॉग जोड़ने होंगे.
FastMixer
और FastCapture
थ्रेड में, इस तरह के कोड का इस्तेमाल करें:
logWriter->log("string"); logWriter->logf("format", parameters); logWriter->logTimestamp();
इस NBLog
टाइमलाइन का इस्तेमाल सिर्फ़ FastMixer
और
FastCapture
थ्रेड करते हैं. इसलिए, एक-दूसरे को बाहर रखने की ज़रूरत नहीं है.
AudioFlinger की अन्य थ्रेड में, mNBLogWriter
का इस्तेमाल करें:
mNBLogWriter->log("string"); mNBLogWriter->logf("format", parameters); mNBLogWriter->logTimestamp();
FastMixer
और FastCapture
के अलावा, दूसरी थ्रेड के लिए,
थ्रेड की NBLog
टाइमलाइन का इस्तेमाल, थ्रेड और बिंडर, दोनों के लिए किया जा सकता है. NBLog::Writer
, हर टाइमलाइन के लिए, एक-दूसरे को म्यूचुअलली एक्सक्लूज़ करने की सुविधा नहीं देता. इसलिए, पक्का करें कि सभी लॉग, ऐसे कॉन्टेक्स्ट में हों जहां थ्रेड का म्यूटेक्स mLock
हो.
लॉग जोड़ने के बाद, AudioFlinger को फिर से बनाएं.
चेतावनी:
थ्रेड की सुरक्षा को पक्का करने के लिए, हर थ्रेड के लिए एक अलग NBLog::Writer
टाइमलाइन ज़रूरी है, क्योंकि टाइमलाइन डिज़ाइन के हिसाब से म्यूटेक्स को हटा देती हैं. अगर आपको एक से ज़्यादा थ्रेड को एक ही टाइमलाइन का इस्तेमाल करना है, तो किसी मौजूदा म्यूटेक्स (mLock
के लिए ऊपर बताए गए तरीके से) की मदद से उसे सुरक्षित किया जा सकता है. इसके अलावा, NBLog::Writer
के बजाय NBLog::LockedWriter
रैपर का इस्तेमाल किया जा सकता है.
हालांकि, इससे इस एपीआई के मुख्य फ़ायदे काफ़ी हद तक खत्म हो जाते हैं: यह ब्लॉक नहीं करता.
NBLog
एपीआई की पूरी जानकारी frameworks/av/include/media/nbaio/NBLog.h
पर मौजूद है.
media.log चालू करना
media.log
डिफ़ॉल्ट रूप से बंद होता है. यह सिर्फ़ तब चालू होता है, जब प्रॉपर्टी
ro.test_harness
1
हो. इसे चालू करने के लिए:
adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot
रीबूट के दौरान कनेक्शन टूट जाता है. इसलिए:
adb shell
ps media
कमांड अब दो प्रोसेस दिखाएगा:
- media.log
- mediaserver
बाद में इस्तेमाल करने के लिए, mediaserver
का प्रोसेस आईडी नोट करें.
टाइमलाइन दिखाना
आपके पास किसी भी समय, लॉग डंप का मैन्युअल तरीके से अनुरोध करने का विकल्प होता है. यह कमांड, सभी चालू और हाल ही की टाइमलाइन के लॉग दिखाता है. इसके बाद, उन्हें मिटा देता है:
dumpsys media.log
ध्यान दें कि डिज़ाइन के हिसाब से टाइमलाइन अलग-अलग होती हैं और टाइमलाइन को मर्ज करने की सुविधा नहीं होती.
मीडिया सर्वर के बंद होने के बाद लॉग वापस पाना
अब mediaserver
प्रोसेस: kill -9 #
को बंद करने की कोशिश करें. यहां #, प्रोसेस आईडी है, जिसे आपने पहले नोट किया था. आपको मुख्य logcat
में media.log
का डंप दिखेगा. इसमें क्रैश से जुड़े सभी लॉग दिखेंगे.
dumpsys media.log