@@ -5,16 +5,25 @@ import android.media.MediaCodec.BufferInfo
55import android.media.MediaFormat
66import android.view.Surface
77import com.pedro.common.TimeUtils
8+ import com.pedro.common.VideoCodec
9+ import com.pedro.common.clone
810import 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}
0 commit comments