Skip to content

Commit 97dc35c

Browse files
committed
add buffer to buffer support in BufferDecoder
1 parent 63cdd8f commit 97dc35c

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

extra-sources/src/main/java/com/pedro/extrasources/BufferDecoder.kt

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,25 @@ import android.media.MediaCodec.BufferInfo
55
import android.media.MediaFormat
66
import android.view.Surface
77
import com.pedro.common.TimeUtils
8+
import com.pedro.common.VideoCodec
9+
import com.pedro.common.clone
810
import com.pedro.encoder.utils.CodecUtil
11+
import java.nio.ByteBuffer
912

10-
class BufferDecoder {
13+
class BufferDecoder(videoCodec: VideoCodec) {
1114

1215
private var codec: MediaCodec? = null
1316
private var mediaFormat: MediaFormat? = null
1417
private var startTs = 0L
1518
private val bufferInfo = BufferInfo()
19+
private val mime = when (videoCodec){
20+
VideoCodec.H264 -> CodecUtil.H264_MIME
21+
VideoCodec.H265 -> CodecUtil.H265_MIME
22+
VideoCodec.AV1 -> CodecUtil.AV1_MIME
23+
}
24+
private var isSurfaceMode = false
1625

17-
fun prepare(width: Int, height: Int, fps: Int, rotation: Int, mime: String) {
26+
fun prepare(width: Int, height: Int, fps: Int, rotation: Int) {
1827
val mediaFormat = MediaFormat()
1928
if (rotation == 0 || rotation == 180) {
2029
mediaFormat.setInteger(MediaFormat.KEY_WIDTH, width)
@@ -28,13 +37,22 @@ class BufferDecoder {
2837
this.mediaFormat = mediaFormat
2938
}
3039

31-
fun start(surface: Surface) {
40+
/**
41+
* @return output raw color. Value indicated in MediaCodecInfo.CodecCapabilities. -1 if not found
42+
*/
43+
fun start(surface: Surface?): Int {
44+
isSurfaceMode = surface != null
3245
mediaFormat?.let {
3346
startTs = TimeUtils.getCurrentTimeMicro()
34-
codec = MediaCodec.createDecoderByType(CodecUtil.H264_MIME)
47+
codec = MediaCodec.createDecoderByType(mime)
3548
codec?.configure(mediaFormat, surface, null, 0)
49+
val color = try {
50+
codec?.outputFormat?.getInteger(MediaFormat.KEY_COLOR_FORMAT) ?: -1
51+
} catch (e: Exception) { -1 }
3652
codec?.start()
53+
return color
3754
}
55+
return -1
3856
}
3957

4058
fun stop() {
@@ -46,10 +64,14 @@ class BufferDecoder {
4664
codec = null
4765
mediaFormat = null
4866
startTs = 0
67+
isSurfaceMode = false
4968
}
5069
}
5170

52-
fun decode(data: ByteArray) {
71+
/**
72+
* @return The frame data in raw format indicated in start method. return null if fail or in surface mode
73+
*/
74+
fun decode(data: ByteArray): ByteBuffer? {
5375
codec?.let {
5476
val inIndex = it.dequeueInputBuffer(10000)
5577
if (inIndex >= 0) {
@@ -59,8 +81,11 @@ class BufferDecoder {
5981
}
6082
val outIndex = it.dequeueOutputBuffer(bufferInfo, 10000)
6183
if (outIndex >= 0) {
62-
it.releaseOutputBuffer(outIndex, true)
84+
val rawData = if (!isSurfaceMode) it.getOutputBuffer(outIndex)?.clone() else null
85+
it.releaseOutputBuffer(outIndex, isSurfaceMode)
86+
return rawData
6387
}
6488
}
89+
return null
6590
}
6691
}

extra-sources/src/main/java/com/pedro/extrasources/BufferVideoSource.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import android.media.MediaCodec
55
import android.media.MediaFormat
66
import android.view.Surface
77
import com.pedro.common.TimeUtils
8+
import com.pedro.common.VideoCodec
89
import com.pedro.common.toByteArray
910
import com.pedro.encoder.Frame
1011
import com.pedro.encoder.input.sources.video.VideoSource
11-
import com.pedro.encoder.utils.CodecUtil
1212
import com.pedro.encoder.utils.yuv.NV21Utils
1313
import com.pedro.encoder.utils.yuv.YUVUtil
1414
import com.pedro.encoder.video.FormatVideoEncoder
@@ -41,7 +41,11 @@ class BufferVideoSource(
4141

4242
override fun onVideoFormat(mediaFormat: MediaFormat) { }
4343
})
44-
private val decoder = BufferDecoder()
44+
private val decoder = BufferDecoder(when (format) {
45+
Format.H265 -> VideoCodec.H265
46+
Format.AV1 -> VideoCodec.AV1
47+
else -> VideoCodec.H264
48+
})
4549
private var scope = CoroutineScope(Dispatchers.IO)
4650
private val queue: BlockingQueue<Frame> = ArrayBlockingQueue(80)
4751

@@ -76,13 +80,8 @@ class BufferVideoSource(
7680
}
7781

7882
override fun create(width: Int, height: Int, fps: Int, rotation: Int): Boolean {
79-
val mime = when (format) {
80-
Format.H265 -> CodecUtil.H265_MIME
81-
Format.AV1 -> CodecUtil.AV1_MIME
82-
else -> CodecUtil.H264_MIME
83-
}
8483
val result = videoEncoder.prepareVideoEncoder(width, height, fps, bitrate, rotation, 2, FormatVideoEncoder.YUV420Dynamical)
85-
decoder.prepare(width, height, fps, rotation, mime)
84+
decoder.prepare(width, height, fps, rotation)
8685
NV21Utils.preAllocateBuffers(width * height * 3 / 2)
8786
return result
8887
}

0 commit comments

Comments
 (0)