我目前正試圖解析來自RTP流的H264數據,然後將其發送到MediaCodec以在Android的SurfaceView上呈現。在Android上使用H264數據解碼RTP流使用MediaCodec
不過,我不能確定如何:
- 從RTP包正確地構建H264片
- 發送H264片的媒體編解碼器一旦被組裝成片
我還沒有看到以清晰簡潔的方式實施的任何示例,我還沒有找到MediaCodec文檔對您有所幫助。
任何人都有這方面的經驗嗎?
void videoCodec(ByteBuffer input, int flags) {
bufferInfo.set(0, 0, 0, flags);
int inputBufferId = codec.dequeueInputBuffer(10000);
if (inputBufferId >= 0) {
//put data
ByteBuffer inputData = inputBuffers[inputBufferId];
inputData.clear();
inputData.put(input);
//queue it up
codec.queueInputBuffer(inputBufferId, 0, input.limit(), 0, flags);
}
int outputBufferId = codec.dequeueOutputBuffer(bufferInfo, 10000);
if (outputBufferId >= 0) {
// outputBuffers[outputBufferId] is ready to be processed or rendered.
Timber.e("Rendering Data with Index of: %s", outputBufferId);
codec.releaseOutputBuffer(outputBufferId, true);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
//format = codec.getOutputFormat();
}
}
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080);
codec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
codec.configure(format, surfaceVideo.getHolder().getSurface(), null, 0);
codec.start();
inputBuffers = codec.getInputBuffers();
outputBuffers = codec.getOutputBuffers();
while (streaming) {
//receive RTP Packet
h264Parser(rtpPacket.getPayload());
}
而且在h264Parser看起來是這樣的:
void h264Parser(byte[] payload) {
int packetType = (byte) payload[0] & (byte) 0x1F;
boolean startBit = (payload[1] & 0x80) != 0;
boolean endBit = (payload[1] & 0x40) != 0;
int flags = 0;
switch (packetType) {
case 7:
pps = new ByteArrayOutputStream();
pps.write(prefix);
pps.write(payload);
break;
case 8:
if (pps.size() > 0) {
pps.write(payload);
hasPps = true;
flags = MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
payload = pps.toByteArray();
//Send packet to decoder
videoCodec(ByteBuffer.wrap(payload), flags);
break;
case 28:
if (hasPps) {
if (startBit) {
baos = new ByteArrayOutputStream();
baos.write(prefix);
baos.write(payload);
} else if (endBit) {
if(baos != null) {
baos.write(payload);
flags = MediaCodec.BUFFER_FLAG_KEY_FRAME;
payload = baos.toByteArray();
//Send packet to decoder
videoCodec(ByteBuffer.wrap(payload), flags);
hasPps = false;
} else {
if(baos != null) {
baos.write(payload);
}
}
}
break;
case 1:
break;
default:
}
你可以使用一些庫來播放實況視頻。我曾與Vitamio合作過,其使用非常簡單:https://www.vitamio.org/en/ – WannaBeGeek
我不是這個庫的作者,但是在做類似的研究時,我發現這個:[AndroidStreamingClient](https: //github.com/ekumenlabs/AndroidStreamingClient)請看這裏的代碼: https://github.com/ekumenlabs/AndroidStreamingClient/blob/master/android_streaming_client/src/main/java/com/c77/androidstreamingclient/lib/rtp /RtpMediaExtractor.java這似乎正在做你正在尋找。 –