הפעלת סרטון HDR

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

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

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

דרישות מוקדמות למכשירים

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

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

איך בודקים אם יש תמיכה בהפעלה באיכות HDR

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

הקוד הבא בודק אם המכשיר תומך בהפעלה בפורמט HLG10. החל מגרסת Android 13, 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.

משאבים

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

HDR

מדיה

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