הפעלת סרטון HDR

HDR, או טווח דינמי גבוה, מספק טווח צבעים רחב יותר וניגודיות גבוהה יותר בין הצבעים הלבנים הבהירים ביותר לבין הצללים הכי כהים, וכתוצאה מכך איכות הסרטון דומה יותר למה שרואים בעין בלתי מזוינת.

אתם יכולים להגדיר באפליקציה הפעלה של סרטוני HDR כדי להציג תצוגה מקדימה של תוכן וידאו ב-HDR ולהפעיל אותו.

במאמר הזה נניח שכבר הוספתם לאפליקציה תמיכה בסיסית בהפעלת סרטונים. למידע נוסף על הפעלה, אפשר לעיין במסמכי העזרה של ExoPlayer.

דרישות סף למכשירים

לא כל מכשירי Android תומכים בהפעלת HDR. לפני שמפעילים תוכן וידאו באיכות HDR באפליקציה, צריך לבדוק אם המכשיר עומד בדרישות המוקדמות הבאות:

  • מטרגטת ל-Android 7.0 ואילך (שכבת API 24).
  • מכיל מקודד שתומך ב-HDR וגישה למסך שתומך ב-HDR.

בדיקת התמיכה בהפעלת HDR

אפשר להשתמש ב-Display.getHdrCapabilities() כדי לשלוח שאילתה לגבי יכולות ה-HDR של המסך. השיטה מחזירה מידע על פרופילי ה-HDR הנתמכים ועל טווח הבהירות של המסך.

הקוד הבא בודק אם המכשיר תומך בהפעלת HLG10. החל מגרסה 13 של Android, HLG10 הוא התקן המינימלי שחייבים לתמוך בו יצרני המכשירים אם המכשיר מסוגל להפעיל HDR:

Kotlin

// Check if display supports the HDR type
val capabilities = display?.hdrCapabilities?.supportedHdrTypes ?: intArrayOf()
if (!capabilities.contains(HDR_TYPE_HLG)) {
  throw RuntimeException("Display does not support desired HDR type");
}

Java

// Check if display supports the HDR type
int[] list = getDisplay().getHdrCapabilities().getSupportedHdrTypes();
List capabilities = Arrays.stream(list).boxed().collect(Collectors.toList());
if (!capabilities.contains(HDR_TYPE_HLG)) {
 throw new RuntimeException("Display does not support desired HDR type");
}

הגדרת הפעלה באיכות HDR באפליקציה

אם האפליקציה שלכם משתמשת ב-ExoPlayer, היא תומכת בהפעלה באיכות HDR כברירת מחדל. במאמר בדיקת התמיכה בהפעלת HDR מוסבר מה צריך לעשות.

אם האפליקציה לא משתמשת ב-ExoPlayer, צריך להגדיר את ההפעלה של HDR באמצעות MediaCodec דרך SurfaceView.

הגדרת MediaCodec באמצעות SurfaceView

מגדירים תהליך הפעלה סטנדרטי של MediaCodec באמצעות SurfaceView. כך תוכלו להציג תוכן וידאו באיכות HDR בלי טיפול מיוחד בהפעלה של HDR:

  • MediaCodec: פענוח של תוכן וידאו HDR.
  • SurfaceView: הצגת תוכן וידאו באיכות HDR.

הקוד הבא בודק אם הקודק תומך בפרופיל HDR, ואז מגדיר את MediaCodec באמצעות SurfaceView:

Kotlin

// Check if there's a codec that supports the specific HDR profile
val list = MediaCodecList(MediaCodecList.REGULAR_CODECS) var format = MediaFormat() /* media format from the container */;
format.setInteger(MediaFormat.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.AV1ProfileMain10)
val codecName = list.findDecoderForFormat (format) ?: throw RuntimeException ("No codec supports the format")

// Here is a standard MediaCodec playback flow
val codec: MediaCodec = MediaCodec.createByCodecName(codecName);
val surface: Surface = surfaceView.holder.surface
val callback: MediaCodec.Callback = (object : MediaCodec.Callback() {
   override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
      queue.offer(index)
   }

   override fun onOutputBufferAvailable(
      codec: MediaCodec,
      index: Int,
      info: MediaCodec.BufferInfo
   ) {
      codec.releaseOutputBuffer(index, timestamp)
   }

   override fun onError(codec: MediaCodec, e: MediaCodec.CodecException) {
      // handle error
   }

   override fun onOutputFormatChanged(
      codec: MediaCodec, format: MediaFormat
   ) {
      // handle format change
   }
})

codec.setCallback(callback)
codec.configure(format, surface, crypto, 0 /* flags */)
codec.start()
while (/* until EOS */) {
   val index = queue.poll()
   val buffer = codec.getInputBuffer(index)
   buffer?.put(/* write bitstream */)
   codec.queueInputBuffer(index, offset, size, timestamp, flags)
}
codec.stop()
codec.release()

Java

// Check if there's a codec that supports the specific HDR profile
MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
MediaFormat format = /* media format from the container */;
format.setInteger(
    MediaFormat.KEY_PROFILE, CodecProfileLevel.AV1ProfileMain10);
String codecName = list.findDecoderForFormat(format);
if (codecName == null) {
    throw new RuntimeException("No codec supports the format");
}

// Below is a standard MediaCodec playback flow
MediaCodec codec = MediaCodec.getCodecByName(codecName);
Surface surface = surfaceView.getHolder().getSurface();
MediaCodec.Callback callback = new MediaCodec.Callback() {
    @Override
    void onInputBufferAvailable(MediaCodec codec, int index) {
        queue.offer(index);
    }

    @Override
    void onOutputBufferAvailable(MediaCodec codec, int index) {
        // release the buffer for render
        codec.releaseOutputBuffer(index, timestamp);
    }

    @Override
    void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
        // handle format change
    }

    @Override
    void onError(MediaCodec codec, MediaCodec.CodecException ex) {
        // handle error
    }

};
codec.setCallback(callback);
codec.configure(format, surface, crypto, 0 /* flags */);
codec.start();
while (/* until EOS */) {
    int index = queue.poll();
    ByteBuffer buffer = codec.getInputBuffer(index);
    buffer.put(/* write bitstream */);
    codec.queueInputBuffer(index, offset, size, timestamp, flags);
}
codec.stop();
codec.release();

הטמעות נוספות של MediaCodec באמצעות SurfaceView זמינות בדוגמאות של Android Camera.

משאבים

מידע נוסף על הפעלת HDR זמין במקורות המידע הבאים:

HDR

מדיה

  • הפניית Media API: מידע נוסף על ממשקי Media API.
  • ExoPlayer: מידע נוסף על הגדרת האפליקציה באמצעות ספריית ExoPlayer.