मेरे पास कुछ स्वचालित परीक्षण हैं जो Android के MediaDecoder और MediaExtractor का उपयोग करके PCM डेटा में कुछ m4a फ़ाइलों को डीकोड करने का प्रयास करते हैं। फ़ाइलें विभिन्न एन्कोडर के साथ उत्पन्न होती हैं: fdk-aac, ffmpeg (एफडीके या डिफ़ॉल्ट एएसी एन्कोडर के साथ), आईओएस।

Android 9 पर ffmpeg के साथ बनाई गई क्लिप के लिए परीक्षण विफल हो जाता है, जिसके परिणामस्वरूप PCM फ़ाइलें खाली हो जाती हैं। एंड्रॉइड के पुराने संस्करणों पर एक ही क्लिप को ठीक से डीकोड किया गया है।

मैंने अपना कोड दोबारा चेक किया और डिकोडिंग प्रक्रिया उम्मीद के मुताबिक चलती है:

  • मैं MediaExtractor का उपयोग करके संपीड़ित डेटा निकालता हूं
  • इसे कोडेक में संलग्न करें
  • कोडेक से आउटपुट बफर को डिक्यू करें।

मुद्दा यह है कि जब तक अंतिम उपलब्ध इनपुट बफ़र को एनक्यू किया जाता है और MediaCodec.BUFFER_FLAG_END_OF_STREAM के साथ आउटपुट बफ़र को हटा दिया जाता है, तब तक सभी आउटपुट बफ़र्स खाली हो जाते हैं!

तब मैंने देखा कि MediaFormat ऑडियो फ़ाइल से निकाली गई जानकारी MediaExtractor.getTrackFormat(int track) में एक गैर-दस्तावेजी "encoder-delay" कुंजी है।

एंड्रॉइड 8 और उससे कम के लिए, वह कुंजी केवल iTunSMPB टैग जानकारी के साथ एन्कोड किए गए m4a क्लिप के लिए मौजूद है। मेरी परीक्षण फ़ाइलों के लिए मुझे मिलने वाले मानों का सारांश यहां दिया गया है:

iOS-encoded file:           2112 frames
fdkaac with iTunSMPB tag:   2048 frames
fdkaac with ISO delay info: key not present
ffmpeg:                     key not present
ffmpeg (fdk):               key not present

Android 9 पर, इसके बजाय, मुझे निम्न परिणाम मिलते हैं:

iOS-encoded file:           2112 frames
fdkaac with iTunSMPB tag:   2048 frames
fdkaac with ISO delay info: 2048 frames
ffmpeg:                     45158 frames
ffmpeg (fdk):               90317 frames

ऐसा लगता है कि कुछ बदल गया है और MediaExtractor अब परीक्षण के तहत सभी फाइलों के लिए एन्कोडर विलंब को पुनः प्राप्त करने में सक्षम है। यह सिद्धांत रूप में अच्छा है, क्योंकि बिना "encoder-delay" जानकारी वाली फाइलें डीकोडेड पीसीएम डेटा में देरी दिखाती हैं (यह एक ज्ञात मुद्दा था)।

लेकिन... जबकि "Fdkaac with ISO देरी की जानकारी" मामले के लिए मान सही है और बिना किसी प्रारंभिक पैडिंग के एक वैध PCM फ़ाइल की ओर ले जाता है (अंत में!), ffmpeg-जनित फ़ाइलों के लिए मान विशाल और संभावित रूप से गलत दिखें!

मुझे पता है कि वास्तविक एन्कोडर विलंब मान ffmpeg मामले के लिए 1024 और ffmpeg (fdk) मामले के लिए 2048 हैं, और मुझे लगता है कि निकाले गए प्रारूप में कुंजी के लिए उच्च मान है यही कारण है कि फाइल खाली है।

वास्तव में, अगर मैं "encoder-delay" को MediaCodec.configure(...) पर भेजने से ठीक पहले प्रारूप में कुंजी को 0 पर सेट करने का प्रयास करता हूं, तो मुझे अपेक्षित देरी के साथ सही असम्पीडित डेटा मिलता है।

इस बिंदु पर मेरा अनुमान है कि MediaExtractor एन्कोडर विलंब मान पुनर्प्राप्ति में कुछ बग है, लेकिन शायद कुछ ऐसा है जिसे मैं देख रहा हूं।

चूंकि ffmpeg काफी लोकप्रिय है, इस बात की काफी संभावना है कि मेरे कई ऐप उपयोगकर्ता इसके साथ उत्पन्न फाइलों को आयात करने का प्रयास करेंगे, और इस बिंदु पर मुझे इस मुद्दे का एक आसान समाधान नहीं दिख रहा है।

क्या किसी के पास कोई सुझाव/कामकाज है?

3
athos 23 अक्टूबर 2018, 13:18

1 उत्तर

सबसे बढ़िया उत्तर

मैंने एंड्रॉइड इश्यू ट्रैकर पर एक मुद्दा खोला: https://issuetracker.google.com/issues/118398811

और अभी के लिए मैंने अभी एक वर्कअराउंड लागू किया है: जब "एनकोडर-देरी" मान MediaFormat ऑब्जेक्ट में मौजूद है और यह असंभव रूप से उच्च मान है, तो मैं इसे शून्य पर सेट करता हूं। कुछ इस तरह:

if (format.containsKey("encoder-delay") && format.getInteger("encoder-delay") > THRESHOLD) {
    format.setInteger("encoder-delay", 0);
}

NB: इसका मतलब है कि शुरुआती अंतर को कम नहीं किया जाएगा, लेकिन M4a फ़ाइलों के लिए जिनके पास ऐसी जानकारी नहीं है, यह पहले से ही Android-9 उपकरणों पर मामला है।

1
athos 25 अक्टूबर 2018, 07:49