我看到了如何使用MediaCodec将视频转换为mp4。这些示例使用的是Surface。
然后我认为h.264 =>解码=>表面=>编码(文件),这是不必要的编码/解码过程。
是否可以使用Android MediaCodec / MediaMuxer将原始的h.264文件mp4进行编码/解码?
更新
我实现了一些引用注释链接(https://developer.android.com/reference/android/media/MediaMuxer)的代码。
while(!finished) {
// getInputBuffer() will fill the inputBuffer with one frame of encoded
// sample from either MediaCodec or MediaExtractor, set isAudioSample to
// true when the sample is audio data, set up all the fields of bufferInfo,
// and return true if there are no more samples.
byte[] tempBuffer = new byte[1000000];
try {
inputBuffer.clear();
int bytesRead = videoFis.read(tempBuffer, 0, inputBuffer.limit());
if(bytesRead <= -1) {
break;
}
else {
inputBuffer.put(tempBuffer, 0, bytesRead);
int currentTrackIndex = videoTrackIndex; // isAudioSample ? audioTrackIndex : videoTrackIndex;
muxer.writeSampleData(currentTrackIndex, inputBuffer, bufferInfo);
}
} catch (IOException e) {
e.printStackTrace();
}
}
上面的代码不起作用。我没有被编码一帧。
// getInputBuffer() will fill the inputBuffer with one frame of encoded
// sample from either MediaCodec or MediaExtractor
要从原始h.264中获取一帧编码,是否应该使用MediaCodec?
Update2
bb.mark();
// read all
while(true) {
try {
int bb2 = videoFis.read(tempBuffer, 0, tempBuffer.length);
if(bb2 != -1) {
bb.put(tempBuffer, 0, bb2);
}
else {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
bb.reset();
int mata[][] = new int[5][256];
mata[0][0] = 1;
mata[1][0] = 2;
mata[2][0] = 3;
mata[3][1] = 4;
int step = 0;
// find first key frame.
while(bb.hasRemaining()) {
step = mata[step][(bb.get() & 0xFF)];
if(step < 4) {
step = mata[step][(bb.get() & 0xFF)];
}
else if(step == 4) {
byte g = bb.get();
if((g & 0x1f) == 5) {
bb.position(bb.position() - 5);
break;
}
}
}
step = 0;
while(!finished) {
int nextPosition = -1;
int offset = bb.position();
bb.get(); bb.get(); bb.get(); bb.get();
byte nalUnit = bb.get();
while(bb.hasRemaining()) {
if(step < 4) {
step = mata[step][(bb.get() & 0xFF)];
}
else if(step == 4) {
byte g = bb.get();
if((g & 0x60) != 0) {
nextPosition = bb.position() - 5;
break;
}
}
}
step = 0;
bufferInfo.flags = (nalUnit & 0x1f) == 5 ? MediaCodec.BUFFER_FLAG_KEY_FRAME : 0;
bufferInfo.offset = offset;
bufferInfo.size = nextPosition - offset;
bufferInfo.presentationTimeUs += 1000 * 1000 / 15;
Log.d(",,", "offset: " + bufferInfo.offset + "..." + "size: " + bufferInfo.size + "..." + "pts: " + bufferInfo.presentationTimeUs);
muxer.writeSampleData(videoTrackIndex, inputBuffer, bufferInfo);
bb.position(nextPosition);
if(bufferInfo.presentationTimeUs >= 666660)
{
bufferInfo.size = 0;
break;
}
}
muxer.stop();
muxer.release();
像上面的实现一样,我发现称为NAL的0x00 0x00 0x00 0x01,我用偏移量,大小,pts填充bufferInfo。但是我收到了消息
...
02-23 17:59:25.131 7597-7738/com.example.ksoo.ballbotpkg I/MPEG4Writer: setStartTimestampUs: 66666
Earliest track starting time: 66666
02-23 17:59:25.131 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 284939...size: 10531...pts: 133332
02-23 17:59:25.132 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 295470...size: 15908...pts: 199998
offset: 311378...size: 20194...pts: 266664
02-23 17:59:25.133 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 331572...size: 20628...pts: 333330
offset: 352200...size: 21346...pts: 399996
02-23 17:59:25.134 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 373546...size: 21407...pts: 466662
02-23 17:59:25.134 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 394953...size: 22494...pts: 533328
02-23 17:59:25.135 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 417447...size: 23230...pts: 599994
02-23 17:59:25.135 7597-7597/com.example.ksoo.ballbotpkg D/,,: offset: 440677...size: 23820...pts: 666660
02-23 17:59:25.136 7597-7597/com.example.ksoo.ballbotpkg I/MPEG4Writer: Normal stop process
02-23 17:59:25.136 7597-7597/com.example.ksoo.ballbotpkg D/MPEG4Writer: Video track stopping. Stop source
Video track source stopping
Video track source stopped
02-23 17:59:25.136 7597-7738/com.example.ksoo.ballbotpkg I/MPEG4Writer: Received total/0-length (10/0) buffers and encoded 10 frames. - Video
02-23 17:59:25.136 7597-7597/com.example.ksoo.ballbotpkg D/MPEG4Writer: Video track stopped. Stop source
Stopping writer thread
02-23 17:59:25.137 7597-7737/com.example.ksoo.ballbotpkg D/MPEG4Writer: 0 chunks are written in the last batch
02-23 17:59:25.137 7597-7597/com.example.ksoo.ballbotpkg D/MPEG4Writer: Writer thread stopped
02-23 17:59:25.138 7597-7597/com.example.ksoo.ballbotpkg I/MPEG4Writer: The mp4 file will not be streamable.
02-23 17:59:25.138 7597-7597/com.example.ksoo.ballbotpkg D/MPEG4Writer: Video track stopping. Stop source
我做错了吗?