Skip to content

Commit

Permalink
fix(core): properly get vp9 level and profile from MediaFormat
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultBee committed Oct 26, 2023
1 parent 98769df commit b0b7e45
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.github.thibaultbee.streampack.internal.utils.av.video.vpx

import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level1
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level11
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level2
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level21
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level3
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level31
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level4
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level41
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level5
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level51
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level52
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level6
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level61
import android.media.MediaCodecInfo.CodecProfileLevel.VP9Level62

enum class Level(val value: Int) {
UNDEFINED(0),
LEVEL_1(10),
LEVEL_11(11),
LEVEL_2(20),
LEVEL_21(21),
LEVEL_3(30),
LEVEL_31(31),
LEVEL_4(40),
LEVEL_41(41),
LEVEL_5(50),
LEVEL_51(51),
LEVEL_52(52),
LEVEL_6(60),
LEVEL_61(61),
LEVEL_62(62);

companion object {
fun fromValue(value: Int) = entries.first { it.value == value }

fun fromMediaFormat(format: Int): Level {
return when (format) {
VP9Level1 -> LEVEL_1
VP9Level11 -> LEVEL_11
VP9Level2 -> LEVEL_2
VP9Level21 -> LEVEL_21
VP9Level3 -> LEVEL_3
VP9Level31 -> LEVEL_31
VP9Level4 -> LEVEL_4
VP9Level41 -> LEVEL_41
VP9Level5 -> LEVEL_5
VP9Level51 -> LEVEL_51
VP9Level52 -> LEVEL_52
VP9Level6 -> LEVEL_6
VP9Level61 -> LEVEL_61
VP9Level62 -> LEVEL_62
else -> UNDEFINED
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.thibaultbee.streampack.internal.utils.av.video.vpx

import android.media.MediaCodecInfo

enum class Profile(val value: Int) {
PROFILE_0(0),
PROFILE_1(1),
PROFILE_2(2),
PROFILE_3(3);

companion object {
fun fromValue(value: Int) = entries.first { it.value == value }

fun fromMediaFormat(mediaCodecProfile: Int) = when (mediaCodecProfile) {
MediaCodecInfo.CodecProfileLevel.VP9Profile0 -> PROFILE_0
MediaCodecInfo.CodecProfileLevel.VP9Profile1 -> PROFILE_1
MediaCodecInfo.CodecProfileLevel.VP9Profile2 -> PROFILE_2
MediaCodecInfo.CodecProfileLevel.VP9Profile3 -> PROFILE_3
else -> throw IllegalArgumentException("Unknown profile: $mediaCodecProfile")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ import java.nio.ByteBuffer
* }
*/
data class VPCodecConfigurationRecord(
private val profile: Byte,
private val level: Byte,
private val profile: Profile,
private val level: Level,
private val bitDepth: Byte,
private val chromaSubsampling: ChromaSubsampling,
private val videoFullRangeFlag: Boolean,
Expand All @@ -60,8 +60,8 @@ data class VPCodecConfigurationRecord(
}

override fun write(output: ByteBuffer) {
output.put(profile)
output.put(level)
output.put(profile.value)
output.put(level.value)
output.put((bitDepth shl 3) or (chromaSubsampling.value shl 1) or (videoFullRangeFlag.toInt()))
output.put(colorPrimaries.value)
output.put(transferCharacteristics.value)
Expand All @@ -82,16 +82,19 @@ data class VPCodecConfigurationRecord(
*
* VP9 [MediaFormat] example:
* ```
* {max-bitrate=1138000, crop-right=359, level=128, mime=video/x-vnd.on2.vp9, profile=1, bitrate=1138000, intra-refresh-period=0, color-standard=4, color-transfer=3, crop-bottom=639, video-qp-average=0, crop-left=0, width=360, bitrate-mode=1, color-range=2, crop-top=0, frame-rate=30, height=640}
* {max-bitrate=1138000, crop-right=359, level=128, mime=video/x-vnd.on2.vp9,
* profile=1, bitrate=1138000, intra-refresh-period=0, color-standard=4, color-transfer=3,
* crop-bottom=639, video-qp-average=0, crop-left=0, width=360, bitrate-mode=1,
* color-range=2, crop-top=0, frame-rate=30, height=640}
* ```
*/
fun fromMediaFormat(format: MediaFormat): VPCodecConfigurationRecord {
val profile = format.getInteger(MediaFormat.KEY_PROFILE)
val profile = Profile.fromMediaFormat(format.getInteger(MediaFormat.KEY_PROFILE))

val level = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
format.getInteger(MediaFormat.KEY_LEVEL)
Level.fromMediaFormat(format.getInteger(MediaFormat.KEY_LEVEL))
} else {
0 // 0 is undefined
Level.UNDEFINED // 0 is undefined
}

val bitDepth = 8 // 8 bits - field is 8 or 10 or 12 bits
Expand Down Expand Up @@ -140,8 +143,8 @@ data class VPCodecConfigurationRecord(
MatrixCoefficients.UNSPECIFIED
}
return VPCodecConfigurationRecord(
profile = profile.toByte(),
level = level.toByte(),
profile = profile,
level = level,
bitDepth = bitDepth.toByte(),
chromaSubsampling = chromaSubsampling,
videoFullRangeFlag = videoFullRangeFlag,
Expand Down

0 comments on commit b0b7e45

Please sign in to comment.