![](/img/trans.png)
[英]Decoding an RTP stream with H264 data on Android Using MediaCodec
[英]decoding android h264 encoded stream on windows using media foundation
我正在嘗試解碼從 Windows pc 上的 android 設備流式傳輸的 h264 編碼的相機幀。 我正在使用 MediaFoundation H264 解碼器來解碼從 android 設備發送的每一幀。 但是我不斷收到錯誤“需要更多輸入樣本來處理輸出錯誤”。
以下是MF H264解碼器的要求:
Media samples contain H.264 bitstream data with start codes and has interleaved SPS/PPS. Each sample contains one complete picture, either one field or one frame.
我想知道這是否與我從 android 設備發送的內容兼容。
我正在使用下面的代碼將幀發送到 Windows 設備:
private static class AvcEncoder {
private MediaCodec mediaCodec;
final static int FRAME_RATE = 15;
final static int MOTION_RANK = 2;
public AvcEncoder(int width, int height) {
mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, (int)(width*height*FRAME_RATE*MOTION_RANK*0.07));
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
}
public void close() {
try {
mediaCodec.stop();
mediaCodec.release();
outputStream.flush();
outputStream.close();
} catch (Exception e){
e.printStackTrace();
}
}
//frames are sent here
public void offerEncoder(byte[] input) {
try {
ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(input);
mediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, 0, 0);
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,0);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
// write frame length
byte frameLength[] = ByteBuffer.allocate(4).putInt(outData.length).array();
outputStream.write(frameLength, 0, 4);
// write the actual frame
outputStream.write(outData, 0, outData.length);
Log.i("AvcEncoder", outData.length + " bytes written");
mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
如果需要,我還可以發布 Windows 代碼。
此外,當我將流數據保存到文件時,我可以在 VLC 中播放它,因此 VLC 能夠很好地理解和解碼它。
嗯,修復很簡單。 我不知道為什么,但 Media Foundation 要求您設置饋送到解碼器的每個樣本的持續時間或時間戳。 然而,輸出似乎不受這兩個參數的任何影響。
編輯:請注意, InputProcess
的方法IMFTransform
應該返回MF_E_NO_SAMPLE_DURATION
或MF_E_NO_SAMPLE_TIMESTAMP
如果樣本持續時間或時間戳沒有在設置IMFSample
傳遞給對象InputProcess
方法。 但是,就我而言,它沒有返回任何此類值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.