Воспроизведение HDR-видео

HDR, или расширенный динамический диапазон, обеспечивает более широкий диапазон цветов и большую контрастность между самыми яркими белыми и самыми темными тенями, в результате чего качество видео больше соответствует тому, что воспринимает невооруженный глаз.

Вы можете настроить воспроизведение видео HDR в своем приложении для предварительного просмотра и воспроизведения видеоконтента HDR.

В этой статье предполагается, что вы уже добавили в свое приложение базовую поддержку воспроизведения видео. Дополнительную информацию о воспроизведении см. в документации ExoPlayer .

Предварительные требования к устройству

Не все устройства Android поддерживают воспроизведение HDR. Прежде чем воспроизводить видеоконтент HDR в приложении, определите, соответствует ли ваше устройство следующим предварительным требованиям:

  • Предназначен для Android 7.0 или более поздней версии (уровень API 24).
  • Имеет декодер с поддержкой HDR и доступ к дисплею с поддержкой HDR.

Проверьте поддержку воспроизведения HDR

Используйте Display.getHdrCapabilities() для запроса возможностей HDR дисплея. Метод возвращает информацию о поддерживаемых профилях HDR и диапазоне яркости дисплея.

Следующий код проверяет, поддерживает ли устройство воспроизведение HLG10. Начиная с Android 13, HLG10 является минимальным стандартом, который производители устройств должны поддерживать, если устройство поддерживает воспроизведение HDR:

Котлин

// 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");
}

Ява

// 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 :

Котлин

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

Ява

// 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

  • Захват видео HDR : узнайте, как настроить захват видео HDR с помощью API-интерфейсов Camera2.
  • Пример Camera2Video на Github : посмотрите работающее приложение с функцией захвата и воспроизведения HDR.

СМИ

,

HDR, или расширенный динамический диапазон, обеспечивает более широкий диапазон цветов и больший контраст между самыми яркими белыми и самыми темными тенями, в результате чего качество видео больше соответствует тому, что воспринимает невооруженный глаз.

Вы можете настроить воспроизведение видео HDR в своем приложении для предварительного просмотра и воспроизведения видеоконтента HDR.

В этой статье предполагается, что вы уже добавили в свое приложение базовую поддержку воспроизведения видео. Дополнительную информацию о воспроизведении см. в документации ExoPlayer .

Предварительные требования к устройству

Не все устройства Android поддерживают воспроизведение HDR. Прежде чем воспроизводить HDR-видео в приложении, определите, соответствует ли ваше устройство следующим предварительным требованиям:

  • Предназначен для Android 7.0 или более поздней версии (уровень API 24).
  • Имеет декодер с поддержкой HDR и доступ к дисплею с поддержкой HDR.

Проверьте поддержку воспроизведения HDR

Используйте Display.getHdrCapabilities() для запроса возможностей HDR дисплея. Метод возвращает информацию о поддерживаемых профилях HDR и диапазоне яркости дисплея.

Следующий код проверяет, поддерживает ли устройство воспроизведение HLG10. Начиная с Android 13, HLG10 является минимальным стандартом, который производители устройств должны поддерживать, если устройство поддерживает воспроизведение HDR:

Котлин

// 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");
}

Ява

// 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 :

Котлин

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

Ява

// 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

  • Захват видео HDR : узнайте, как настроить захват видео HDR с помощью API-интерфейсов Camera2.
  • Пример Camera2Video на Github : посмотрите работающее приложение с функцией захвата и воспроизведения HDR.

СМИ