HDR-Videowiedergabe

HDR (High Dynamic Range) bietet eine größere Farbpalette und einen höheren Kontrast zwischen den hellsten Weißtönen und den dunkelsten Schatten. Dadurch wird eine Videoqualität erzielt, die der Wahrnehmung des bloßen Auges näher kommt.

Du kannst die HDR-Videowiedergabe in deiner App einrichten, um HDR-Videoinhalte in der Vorschau anzusehen und wiederzugeben.

In diesem Artikel wird davon ausgegangen, dass Sie Ihrer App bereits die grundlegende Unterstützung für die Videowiedergabe hinzugefügt haben. Weitere Informationen zur Wiedergabe finden Sie in der ExoPlayer-Dokumentation.

Gerätevoraussetzungen

Nicht alle Android-Geräte unterstützen die HDR-Wiedergabe. Bevor du HDR-Videoinhalte in deiner App wiedergibst, solltest du prüfen, ob dein Gerät die folgenden Voraussetzungen erfüllt:

  • Ausrichtung auf Android 7.0 oder höher (API-Ebene 24)
  • Das Gerät hat einen HDR-fähigen Decoder und Zugriff auf ein HDR-fähiges Display.

Unterstützung für HDR-Wiedergabe prüfen

Mit Display.getHdrCapabilities() kannst du die HDR-Funktionen eines Displays abfragen. Die Methode gibt Informationen zu den unterstützten HDR-Profilen und zum Luminanzbereich des Displays zurück.

Mit dem folgenden Code wird geprüft, ob das Gerät die HLG10-Wiedergabe unterstützt. Ab Android 13 ist HLG10 der Mindeststandard, den Gerätehersteller unterstützen müssen, wenn das Gerät HDR-Wiedergabe unterstützt:

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-Wiedergabe in Ihrer App einrichten

Wenn Ihre App ExoPlayer verwendet, unterstützt sie standardmäßig die HDR-Wiedergabe. Weitere Informationen findest du unter Unterstützung für HDR-Wiedergabe prüfen.

Wenn deine App ExoPlayer nicht verwendet, richte die HDR-Wiedergabe mit MediaCodec über SurfaceView ein.

MediaCodec mit SurfaceView einrichten

Richten Sie mit SurfaceView einen standardmäßigen MediaCodec-Wiedergabeablauf ein. So können Sie HDR-Videoinhalte ohne besondere Verarbeitung für die HDR-Wiedergabe anzeigen:

  • MediaCodec: Decodiert HDR-Videoinhalte.
  • SurfaceView: Zeigt HDR-Videoinhalte an.

Im folgenden Code wird geprüft, ob der Codec das HDR-Profil unterstützt. Anschließend wird MediaCodec mit SurfaceView eingerichtet:

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();

Weitere MediaCodec-Implementierungen mit SurfaceView findest du in den Android-Kamerabeispielen.

Ressourcen

Weitere Informationen zur HDR-Wiedergabe finden Sie in den folgenden Ressourcen:

HDR

Medien

  • Media API-Referenz: Weitere Informationen zu den Media APIs.
  • ExoPlayer: Hier erfahren Sie, wie Sie Ihre App mit der ExoPlayer-Bibliothek einrichten.