एचडीआर ल्यूमिनेंस को एसडीआर के साथ काम करने वाली रेंज के साथ टोन मैप करना

Android 13 में, वेंडर के हिसाब से कॉन्फ़िगर की जा सकने वाली स्टैटिक लाइब्रेरी libtonemap पेश की गई है. यह टोन मैपिंग के ऑपरेशन तय करती है और इसे SurfaceFlinger प्रोसेस और Hardware Composer (HWC) के साथ शेयर किया जाता है. इस सुविधा की मदद से ओईएम, फ़्रेमवर्क और वेंडर के बीच डिसप्ले टोन मैपिंग के एल्गोरिदम को तय और शेयर कर सकते हैं. इससे टोन मैपिंग में अंतर कम हो जाता है.

Android 13 से पहले, डिसप्ले के हिसाब से टोन मैपिंग की प्रोसेस, HWC, SurfaceFlinger, और ऐप्लिकेशन के बीच शेयर नहीं की जाती थी. रेंडरिंग पाथ के आधार पर, एचडीआर कॉन्टेंट के लिए इमेज क्वालिटी में अंतर आ जाता था. ऐसा इसलिए होता था, क्योंकि एचडीआर कॉन्टेंट को अलग-अलग तरीकों से आउटपुट स्पेस में टोन मैप किया जाता था. यह समस्या, स्क्रीन रोटेशन जैसे मामलों में देखी गई. इनमें कंपोज़िशन की रणनीति, GPU और DPU के बीच बदलती है. साथ ही, TextureView और SurfaceView के बीच रेंडरिंग के व्यवहार में अंतर होता है.

इस पेज पर, libtonemap लाइब्रेरी के इंटरफ़ेस, पसंद के मुताबिक बनाने, और पुष्टि करने की जानकारी दी गई है.

टोन मैपिंग लाइब्रेरी का इंटरफ़ेस

libtonemap लाइब्रेरी में सीपीयू पर काम करने वाले फ़ंक्शन और SkSL शेडर होते हैं. इन्हें SurfaceFlinger, GPU-बैकएंड कंपोज़िशन के लिए और HWC, टोन मैपिंग लुक-अप टेबल (एलयूटी) जनरेट करने के लिए इस्तेमाल कर सकता है. libtonemap का एंट्री पॉइंट android::tonemap::getToneMapper() है. यह एक ऐसा ऑब्जेक्ट दिखाता है जो ToneMapper इंटरफ़ेस को लागू करता है.

ToneMapper इंटरफ़ेस में ये सुविधाएं उपलब्ध हैं:

  • टोन-मैपिंग LUT जनरेट करना

    इंटरफ़ेस ToneMapper::lookupTonemapGain, libtonemap_LookupTonemapGain() में तय किए गए शेडर का सीपीयू इम्प्लीमेंटेशन है. इसका इस्तेमाल फ़्रेमवर्क में यूनिट टेस्ट के लिए किया जाता है. साथ ही, पार्टनर इसका इस्तेमाल अपनी कलर पाइपलाइन में टोन-मैपिंग एलयूटी जनरेट करने में मदद पाने के लिए कर सकते हैं.

    libtonemap_LookupTonemapGain(), लीनियर आरजीबी और XYZ, दोनों में लीनियर स्पेस में रंग की वैल्यू लेता है. यह वैल्यू, ऐब्सलूट और अननॉर्मलाइज़्ड होती है. साथ ही, यह एक फ़्लोट दिखाता है, जिससे पता चलता है कि लीनियर स्पेस में इनपुट रंगों को कितना गुणा करना है.

  • SkSL शेडर जनरेट करना

    यह इंटरफ़ेस ToneMapper::generateTonemapGainShaderSkSL(), सोर्स और डेस्टिनेशन डेटास्पेस के हिसाब से SkSL शेडर स्ट्रिंग दिखाता है. SkSL शेडर को RenderEngine के लिए Skia में प्लग किया जाता है. यह SurfaceFlinger के लिए, जीपीयू की मदद से कंपोज़िटिंग करने वाला कॉम्पोनेंट है. शेडर को libhwui में भी प्लग किया जाता है, ताकि TextureView के लिए एचडीआर से एसडीआर टोन मैपिंग को बेहतर तरीके से किया जा सके. जनरेट की गई स्ट्रिंग को Skia के इस्तेमाल किए गए अन्य SkSL शेडर में इनलाइन किया जाता है. इसलिए, शेडर को इन नियमों का पालन करना होगा:

    • शेडर स्ट्रिंग में float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz) सिग्नेचर वाला एंट्री पॉइंट होना चाहिए. इसमें linearRGB, लीनियर स्पेस में RGB पिक्सल के ऐब्सलूट निट्स की वैल्यू होती है और xyz, linearRGB को XYZ में बदला गया होता है.
    • शेडर स्ट्रिंग में इस्तेमाल किए गए किसी भी हेल्पर तरीके के नाम की शुरुआत libtonemap_ से होनी चाहिए, ताकि फ़्रेमवर्क शेडर की परिभाषाएं एक-दूसरे से न टकराएं. इसी तरह, यूनिफ़ॉर्म के इनपुट में in_libtonemap_ प्रीफ़िक्स होना चाहिए.
  • SkSL यूनिफ़ॉर्म जनरेट करना

    इंटरफ़ेस ToneMapper::generateShaderSkSLUniforms(), अलग-अलग एचडीआर स्टैंडर्ड और डिसप्ले की स्थितियों के मेटाडेटा struct के बारे में जानकारी देता है. जैसे:

    • SkSL शेडर से बंधी यूनिफ़ॉर्म की सूची.

    • एक जैसी वैल्यू in_libtonemap_displayMaxLuminance और in_libtonemap_inputMaxLuminance. इन वैल्यू का इस्तेमाल फ़्रेमवर्क शेडर करते हैं. ऐसा तब किया जाता है, जब इनपुट को libtonemap में स्केल किया जाता है और आउटपुट को ज़रूरत के हिसाब से नॉर्मलाइज़ किया जाता है.

    फ़िलहाल, यूनिफ़ॉर्म जनरेट करने की प्रोसेस में इनपुट और आउटपुट डेटास्पेस का इस्तेमाल नहीं किया जाता है.

पसंद के मुताबिक बनाएं

libtonemap लाइब्रेरी के रेफ़रंस के तौर पर लागू करने से, सही नतीजे मिलते हैं. हालांकि, जीपीयू कंपोज़िशन में इस्तेमाल किया गया टोन मैपिंग एल्गोरिदम, डीपीयू कंपोज़िशन में इस्तेमाल किए गए एल्गोरिदम से अलग हो सकता है. इसलिए, रेफ़रंस इंप्लीमेंटेशन का इस्तेमाल करने से, कुछ स्थितियों में फ़्लिकर हो सकता है. जैसे, रोटेशन ऐनिमेशन. कस्टम इमेज से, वेंडर के हिसाब से इमेज क्वालिटी से जुड़ी ऐसी समस्याएं ठीक की जा सकती हैं.

ओईएम को libtonemap के लागू करने के तरीके को बदलने का सुझाव दिया जाता है, ताकि वे अपनी ToneMapper सबक्लास तय कर सकें. यह सबक्लास getToneMapper() से मिलती है. लागू करने के तरीके को पसंद के मुताबिक बनाने के दौरान, पार्टनर को इनमें से कोई एक काम करना होगा:

  • libtonemap को लागू करने के तरीके में सीधे तौर पर बदलाव करें.
  • अपनी स्टैटिक लाइब्रेरी तय करें, लाइब्रेरी को स्टैंडअलोन के तौर पर कंपाइल करें, और libtonemap लाइब्रेरी के .a फ़ाइल को अपनी कस्टम लाइब्रेरी से जनरेट की गई फ़ाइल से बदलें.

वेंडर को किसी भी कर्नल कोड में बदलाव करने की ज़रूरत नहीं है. हालांकि, कई वेंडर को सही तरीके से लागू करने के लिए, डीपीयू टोन-मैपिंग एल्गोरिदम के बारे में जानकारी देनी होगी.

Validation

लागू करने की पुष्टि करने के लिए, यह तरीका अपनाएं:

  1. एचडीआर वीडियो को किसी भी ऐसे एचडीआर स्टैंडर्ड की स्क्रीन पर चलाएं जिसे आपका डिसप्ले सिस्टम सपोर्ट करता हो. जैसे, HLG, HDR10, HDR10+ या DolbyVision.

  2. जीपीयू कंपोज़िशन को टॉगल करें, ताकि यह पक्का किया जा सके कि उपयोगकर्ता को फ़्लिकर न दिखे.

    जीपीयू कंपोज़िशन को टॉगल करने के लिए, इस adb कमांड का इस्तेमाल करें:

    adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
    1 to force GPU composition>
    
    

सामान्य समस्याएं

इस तरीके को लागू करने पर, ये समस्याएं हो सकती हैं:

  • बैंडिंग तब होती है, जब जीपीयू कंपोज़िशन के लिए इस्तेमाल किया गया रेंडर टारगेट, एचडीआर कॉन्टेंट की सामान्य वैल्यू से कम सटीक होता है. उदाहरण के लिए, बैंडिंग तब हो सकती है, जब एचडीआर के लिए HWC लागू करने वाला कोई सिस्टम, RGBA1010102 या P010 जैसे ओपेक 10-बिट फ़ॉर्मैट के साथ काम करता हो. हालांकि, इसके लिए ज़रूरी है कि GPU कंपोज़िशन, ऐल्फ़ा को सपोर्ट करने के लिए RGBA8888 जैसे 8-बिट फ़ॉर्मैट में लिखे.

  • अगर डीपीयू, जीपीयू की तुलना में अलग प्रेसिज़न पर काम करता है, तो क्वानटाइज़ेशन में अंतर की वजह से रंग में थोड़ा बदलाव होता है.

ये सभी समस्याएं, हार्डवेयर की सटीक जानकारी में अंतर की वजह से होती हैं. आम तौर पर, इस समस्या को हल करने के लिए यह पक्का किया जाता है कि कम सटीक पाथ में डिथरिंग का चरण हो. इससे, सटीक अंतर को इंसानों के लिए कम से कम समझा जा सकता है.