google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.71k stars 6.02k forks source link

Is it possible to determine video bit depth (8 bit, 10 bit, etc) ? #8304

Closed Ste-RH closed 3 years ago

Ste-RH commented 3 years ago

[REQUIRED] Searched documentation and issues

I have hunted through ExoPlayer git issues, stack overflow and Android API documentation.

[REQUIRED] Question

I am hunting for a way to determine the bit depth of a video either prior to, or during playback. Is there anyway to determine if a video is 8-bit, 10bit, etc?

christosts commented 3 years ago

I don't think there's an easy way to reliably figure this out. The ultimate source of truth is in the media bitstream, but ExoPlayer does not go into that level of depth, and color depth information cannot be obtained from the platform (MediaCodec) reliably either.

There may be a few cases ExoPlayer can offer a hint based on the codec profile level, but this seems to be specific to the kind of media played. May I ask what kind of media you are currently using? For example, is it DASH content or something else?

Ste-RH commented 3 years ago

It will be user content, so absolutely anything under the sun that ExoPlayer supports!

christosts commented 3 years ago

You may be able to get a hint with the following: set a VideoFrameMetadataListener on the player instance. This should raise a callback for each frame just before is sent to the screen. The callback contains among others, a Format argument (ExoPlayer's representation for media formats), and a MediaFormat (Android's MediaCodec format representation).

From format, you can inspect the Format.codecs field: according to the decoder used, the standardized codec strings indicate the codec profile level, which may indicate the color depth. For exampe in HEVC, to my knowledge, hev1.2.XXXX indicate main profile 10. You can follow the code in MediaCodecUtil to see how profile levels are identified.

From MediaFormat you can get the color-format parameter with MediaFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT) and the returned int values are defined in android.media.MediaCodecInfo.CodecCapabilities. My understanding is that the returned value may vary based on device/vendor implementation, so I'm not sure how reliable this information is.

Important: The VideoFrameMetadataListener callbacks are called on the playback thread and you shouldn't do any blocking operation in there.