Skip to content

Commit

Permalink
refactor(core): replace CodecSurface by the SurfaceProcessor
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultBee committed Nov 14, 2024
1 parent ad9a5a4 commit bd78018
Show file tree
Hide file tree
Showing 53 changed files with 3,176 additions and 1,122 deletions.
3 changes: 2 additions & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.activity)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.androidx.window)
implementation(libs.androidx.concurrent.futures)

testImplementation(libs.androidx.test.rules)
testImplementation(libs.androidx.test.core.ktx)
Expand All @@ -28,7 +30,6 @@ dependencies {
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.robolectric)


androidTestImplementation(libs.androidx.test.core.ktx)
androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.junit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ import android.media.MediaFormat
import android.media.MediaFormat.KEY_PRIORITY
import android.os.Build
import android.util.Size
import androidx.annotation.IntRange
import io.github.thibaultbee.streampack.core.internal.encoders.mediacodec.MediaCodecHelper
import io.github.thibaultbee.streampack.core.internal.utils.RotationValue
import io.github.thibaultbee.streampack.core.internal.utils.av.video.DynamicRangeProfile
import io.github.thibaultbee.streampack.core.internal.utils.extensions.isDevicePortrait
import io.github.thibaultbee.streampack.core.internal.utils.extensions.isVideo
import io.github.thibaultbee.streampack.core.internal.utils.extensions.landscapize
import io.github.thibaultbee.streampack.core.internal.utils.extensions.portraitize
import io.github.thibaultbee.streampack.core.internal.utils.extensions.rotateFromNaturalOrientation
import io.github.thibaultbee.streampack.core.internal.utils.extensions.rotationToDegrees
import io.github.thibaultbee.streampack.core.streamers.DefaultStreamer
import java.security.InvalidParameterException
import kotlin.math.roundToInt
Expand Down Expand Up @@ -153,20 +154,6 @@ class VideoConfig(
*/
val isHdr by lazy { dynamicRangeProfile != DynamicRangeProfile.sdr }

/**
* Get resolution according to device orientation
*
* @param context activity context
* @return oriented resolution
*/
fun getDeviceOrientedResolution(context: Context): Size {
return if (context.isDevicePortrait) {
resolution.portraitize
} else {
resolution.landscapize
}
}

/**
* Get the media format from the video configuration
*
Expand Down Expand Up @@ -348,3 +335,24 @@ class VideoConfig(
}
}

/**
* Rotates video configuration to [rotation] from device natural orientation.
*/
fun VideoConfig.rotateFromNaturalOrientation(context: Context, @RotationValue rotation: Int) =
rotateDegreesFromNaturalOrientation(context, rotation.rotationToDegrees)

/**
* Rotatse video configuration to [rotationDegrees] from device natural orientation.
*/
fun VideoConfig.rotateDegreesFromNaturalOrientation(
context: Context,
@IntRange(from = 0, to = 359) rotationDegrees: Int
): VideoConfig {
val newResolution = resolution.rotateFromNaturalOrientation(context, rotationDegrees)
return if (resolution != newResolution) {
copy(resolution = newResolution)
} else {
this
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.github.thibaultbee.streampack.core.internal.encoders

import android.view.Surface
import io.github.thibaultbee.streampack.core.data.Config
import io.github.thibaultbee.streampack.core.internal.data.Frame
import io.github.thibaultbee.streampack.core.internal.interfaces.Releaseable
import io.github.thibaultbee.streampack.core.internal.interfaces.SuspendStreamable
Expand Down Expand Up @@ -62,6 +63,12 @@ interface IEncoder {

interface IEncoderInternal : SuspendStreamable, Releaseable,
IEncoder {

/**
* The encoder configuration
*/
val config: Config

interface IListener {
/**
* Calls when an encoder has an error.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/*
* Copyright (C) 2024 Thibault B.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.thibaultbee.streampack.core.internal.encoders.mediacodec

import android.media.MediaCodecInfo
Expand All @@ -6,7 +21,6 @@ import android.os.Build
import io.github.thibaultbee.streampack.core.data.AudioConfig
import io.github.thibaultbee.streampack.core.data.Config
import io.github.thibaultbee.streampack.core.data.VideoConfig
import io.github.thibaultbee.streampack.core.internal.orientation.ISourceOrientationProvider

sealed class EncoderConfig<T : Config>(val config: T) {
/**
Expand Down Expand Up @@ -39,13 +53,12 @@ sealed class EncoderConfig<T : Config>(val config: T) {

class VideoEncoderConfig(
videoConfig: VideoConfig,
val useSurfaceMode: Boolean = true,
private val orientationProvider: ISourceOrientationProvider? = null
val useSurfaceMode: Boolean = true
) : EncoderConfig<VideoConfig>(
videoConfig
) {
override val isVideo = true

override fun buildFormat(withProfileLevel: Boolean): MediaFormat {
val format = config.getFormat(withProfileLevel)
if (useSurfaceMode) {
Expand All @@ -68,31 +81,19 @@ class VideoEncoderConfig(
return format
}

fun orientateFormat(format: MediaFormat) {
orientationProvider?.let {
it.getOrientedSize(config.resolution).apply {
// Override previous format
format.setInteger(MediaFormat.KEY_WIDTH, width)
format.setInteger(MediaFormat.KEY_HEIGHT, height)
}
}
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is VideoEncoderConfig) return false

if (!super.equals(other)) return false
if (useSurfaceMode != other.useSurfaceMode) return false
if (orientationProvider != other.orientationProvider) return false

return true
}

override fun hashCode(): Int {
var result = super.hashCode()
result = 31 * result + useSurfaceMode.hashCode()
result = 31 * result + (orientationProvider?.hashCode() ?: 0)
result = 31 * result + isVideo.hashCode()
return result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import android.media.MediaFormat
import android.os.Bundle
import android.util.Log
import android.view.Surface
import io.github.thibaultbee.streampack.core.data.Config
import io.github.thibaultbee.streampack.core.internal.data.Frame
import io.github.thibaultbee.streampack.core.internal.encoders.IEncoderInternal
import io.github.thibaultbee.streampack.core.internal.encoders.mediacodec.extensions.hasEndOfStreamFlag
Expand Down Expand Up @@ -85,7 +86,8 @@ internal constructor(
}
}


override val config = encoderConfig.config

private val encoderCallback = EncoderCallback()

init {
Expand Down Expand Up @@ -128,15 +130,6 @@ internal constructor(
}

override fun configure() {
/**
* This is a workaround because few Samsung devices (such as Samsung Galaxy J7 Prime does
* not find any encoder if the width and height are oriented to portrait.
* We defer orientation of width and height to here.
*/
if (encoderConfig is VideoEncoderConfig) {
encoderConfig.orientateFormat(format)
}

try {
/**
* Set encoder callback without handler.
Expand Down
Loading

0 comments on commit bd78018

Please sign in to comment.