इस लेख में, 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/audioflingerConfiguration.hमें बदलाव करें.#define TEE_SINKसे टिप्पणी हटाएं.libaudioflinger.soको फिर से बनाएं.adb rootadb remount- नए
libaudioflinger.soको डिवाइस के/system/libपर पुश या सिंक करें.
रन-टाइम सेटअप
adb shell getprop | grep ro.debuggable
पुष्टि करें कि आउटपुट:[ro.debuggable]: [1]adb shellls -ld /data/misc/audioserver
पुष्टि करें कि आउटपुट:
drwx------ media media ... media
अगर डायरेक्ट्री मौजूद नहीं है, तो उसे इस तरह बनाएं:
mkdir /data/misc/audioserverchown media:media /data/misc/audioserverecho af.tee=# > /data/local.prop
यहांaf.teeवैल्यू, नीचे बताई गई संख्या है.chmod 644 /data/local.propreboot
af.tee प्रॉपर्टी की वैल्यू
af.tee की वैल्यू 0 से 7 के बीच की कोई संख्या होती है. यह वैल्यू, हर सुविधा के लिए एक बिट के हिसाब से कई बिट का जोड़ होती है.
हर बिट के बारे में कम शब्दों में जानकारी पाने के लिए, AudioFlinger.cpp में AudioFlinger::AudioFlinger() पर मौजूद कोड देखें:
- 1 = इनपुट
- 2 = FastMixer आउटपुट
- 4 = हर ट्रैक के लिए AudioRecord और AudioTrack
फ़िलहाल, डीप बफ़र या सामान्य मिक्सर के लिए कोई बिट नहीं है. हालांकि, "4" का इस्तेमाल करके मिलते-जुलते नतीजे मिल सकते हैं.
डेटा की जांच करना और उसे हासिल करना
- ऑडियो की जांच करें.
adb shell dumpsys media.audio_flingerdumpsysआउटपुट में ऐसी लाइन ढूंढें:
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 shellrm /data/local.proprm /data/misc/audioserver/*.wavreboot
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 rootadb shellecho ro.test_harness=1 > /data/local.propchmod 644 /data/local.propreboot
रीबूट के दौरान कनेक्शन टूट जाता है. इसलिए:
adb shell
ps media कमांड अब दो प्रोसेस दिखाएगा:
- media.log
- mediaserver
बाद में इस्तेमाल करने के लिए, mediaserver का प्रोसेस आईडी नोट करें.
टाइमलाइन दिखाना
आपके पास किसी भी समय, लॉग डंप का मैन्युअल तरीके से अनुरोध करने का विकल्प होता है. यह कमांड, सभी चालू और हाल ही की टाइमलाइन के लॉग दिखाता है. इसके बाद, उन्हें मिटा देता है:
dumpsys media.log
ध्यान दें कि डिज़ाइन के हिसाब से टाइमलाइन अलग-अलग होती हैं और टाइमलाइन को मर्ज करने की सुविधा नहीं होती.
मीडिया सर्वर के बंद होने के बाद लॉग वापस पाना
अब mediaserver प्रोसेस: kill -9 # को बंद करने की कोशिश करें. यहां #, प्रोसेस आईडी है, जिसे आपने पहले नोट किया था. आपको मुख्य logcat में media.log का डंप दिखेगा. इसमें क्रैश से जुड़े सभी लॉग दिखेंगे.
dumpsys media.log