如何解决无法从Java / Kotlin中的ByteArray解码h264帧
正在开发需要从TCP连接中来自我们服务器的byteArrays解码h264的应用程序。我有帧插入,并且能够分解SPS和PPS,但是当将帧馈送到解码器时,纹理或表面视图上没有任何显示(都尝试过)
fun decode()
{
while(run) {
if (frameQueue.size >= 1) {
val frameFromQue = frameQueue.remove() //Grab frame from queue
var startCode = byteArrayOf(0,1)
var decodeDataBuffer: ByteBuffer? = null
decodeDataBuffer = ByteBuffer.wrap(startCode + frameFromQue)
// Get the input buffer from the decoder
val inputIndex: Int =
mDecodeMediaCodec.dequeueInputBuffer(-1)
// If the buffer number is valid use the buffer with that index
if (inputIndex >= 0) {
if (firstInputTimeNsec == -1L) {
firstInputTimeNsec = System.nanoTime()
}
val buffer: ByteBuffer? = mDecodeMediaCodec.getInputBuffer(inputIndex)
buffer!!.clear()
buffer.put(decodeDataBuffer!!.array())
mDecodeMediaCodec.queueInputBuffer(
inputIndex,decodeDataBuffer.array().size,pTime,0
)
decodeDataBuffer.clear()
pTime += 33000
}
val decoderStatus: Int =
mDecodeMediaCodec.dequeueOutputBuffer(mBufferInfo,TIMEOUT_USEC.toLong())
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
// no output available yet
if (VERBOSE) Log.d(
"decode","no output from decoder available"
)
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
// not important for us,since we're using Surface
if (VERBOSE) Log.d(
"decode","decoder output buffers changed"
)
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
val newFormat: MediaFormat = mDecodeMediaCodec.getOutputFormat()
if (VERBOSE) Log.d(
"decode","decoder output format changed: $newFormat"
)
} else if (decoderStatus < 0) {
throw RuntimeException(
"unexpected result from decoder.dequeueOutputBuffer: " +
decoderStatus
)
} else { // decoderStatus >= 0
if (firstInputTimeNsec != 0L) {
// Log the delay from the first buffer of input to the first buffer
// of output.
val nowNsec = System.nanoTime()
Log.d(
"decode","startup lag " + (nowNsec - firstInputTimeNsec) / 1000000.0 + " ms"
)
firstInputTimeNsec = 0
}
val doRender = mBufferInfo.size != 0
mDecodeMediaCodec.releaseOutputBuffer(decoderStatus,doRender)
}
}
}
}
fun initDecodeMediaCodec(width:Int,height:Int):Boolean {
// Create the format settinsg for the MediaCodec
try
{
println("Setting up decoder...")
val format = MediaFormat.createVideoFormat(
MediaFormat.MIMETYPE_VIDEO_AVC,width,height
) // MIMETYPE: a two-part identifier for file formats and format contents
var startCode = byteArrayOf(0,1)
// Set the PPS and SPS frame
format.setByteBuffer("csd-0",ByteBuffer.wrap(startCode + player.sps!!))
format.setByteBuffer("csd-1",ByteBuffer.wrap(startCode + player.pps!!))
try {
// Get an instance of MediaCodec and give it its Mime type
mDecodeMediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC)
mDecodeMediaCodec.configure(format,mSurface.holder.surface,null,0)
// Start the codec
mDecodeMediaCodec.start()
adjustAspectRatio(width,height)
Thread(Runnable {//Start decoding frames on another thread
decode()
}).start()
return true
} catch (e: Exception) {
return false
e.printStackTrace()
}
}
catch(e:java.lang.Exception)
{
return false
println("Error while connecting: $e")
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。