作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 MediaCodec(和 SurfaceView)在 Android 上渲染一个 h.264 视频。这是我的一些代码。
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (videoPlayer == null) {
videoPlayer = new PlayerThread(holder.getSurface());
videoPlayer.start();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (videoPlayer != null) {
videoPlayer.interrupt();
videoPlayer.isEOS = true;
videoPlayer = null;
}
}
private class PlayerThread extends Thread {
private MediaCodec decoder;
private Surface surface;
private final static String mimeType = "video/avc";
public boolean isEOS = false;
public PlayerThread(Surface surface) {
this.surface = surface;
}
@Override
public void run() {
MediaFormat format = MediaFormat.createVideoFormat(mimeType, frame.width, frame.height);
decoder = MediaCodec.createDecoderByType(mimeType);
decoder.configure(format, surface, null, 0);
decoder.start();
ByteBuffer[] inputBuffers = decoder.getInputBuffers();
ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
int startPTS = 0;
while (!Thread.interrupted() && !isEOS) {
frame = frameReader.nextFrame();
if (startPTS == 0) {
startPTS = frame.pts;
}
int relativePTS = frame.pts - startPTS;
int inIndex = decoder.dequeueInputBuffer(-1);
if (inIndex >= 0)
{
ByteBuffer inputBuffer = inputBuffers[inIndex];
inputBuffer.clear();
inputBuffer.put(frame.buf, 0, frame.size);
decoder.queueInputBuffer(inIndex, 0, frame.size, relativePTS*1000, 0);
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
int outIndex = decoder.dequeueOutputBuffer(info, -1);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = decoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.d("DecodeActivity", "New format " + decoder.getOutputFormat());
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer outputBuffer = outputBuffers[outIndex];
Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + outputBuffer);
decoder.releaseOutputBuffer(outIndex, true);
}
}
/* clean */
decoder.stop();
decoder.release();
decoder = null;
}
}
我设置了 PTS,但它不起作用。视频播放速度非常快。
有人知道如何在这种情况下设置正确的呈现时间戳吗?任何帮助将不胜感激。
最佳答案
使用 MediaCodec 解码视频时,您不是设置 PTS 的人,您是接收 PTS 的人。当您调用设置了“渲染”标志的 releaseOutputBuffer()
时,您是在告诉系统尽快渲染帧。您有责任控制框架的节奏。
有关控制播放速率的基于 MediaCodec 的视频播放器的示例,请参阅 Grafika , 特别是 SpeedControlCallback 的使用类。
关于android - 如何在 Android MediaCodec 中设置演示文稿时间戳?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30472871/
我是一名优秀的程序员,十分优秀!