使用MediaSync的Android应用在播放视频时冻结

宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述使用MediaSync的Android应用在播放视频时冻结相关的知识,希望能为你提供帮助。
我正在尝试使用新的MediaSync API来同步播放视频和音频。 https://developer.android.com/reference/android/media/MediaSync.html
我有使用MediaSync的Audio Only播放器,但是对于Video only播放器,我在显示5-6帧后立即在logcat中得到它

I/MediaSync﹕ still waiting to release a buffer before acquire

我的视频播放器如下所示
public class VideoDecoderTask implements Runnable { ...... @Override public void run() {mediaSync = new MediaSync(); mediaSync.setSurface(surface); Surface inputSurface = mediaSync.createInputSurface(); mediaExtractor = new MediaExtractor(); try { mediaExtractor.setDataSource(this.clipPath); } catch (IOException e1) { e1.printStackTrace(); }for (int i = 0; i < mediaExtractor.getTrackCount(); i++) { MediaFormat format = mediaExtractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { Log.d(LOG_TAG, format.toString()); mediaExtractor.selectTrack(i); try { videoDecoder = MediaCodec.createDecoderByType(mime); } catch (IOException e) { e.printStackTrace(); } videoDecoder.configure(format, inputSurface, null, 0); Log.d(LOG_TAG, "Found a video track."); break; } }SyncParams syncParams = new SyncParams(); syncParams.setSyncSource(SyncParams.SYNC_SOURCE_VSYNC); mediaSync.setPlaybackParams(new PlaybackParams().setSpeed(1.f)); mediaSync.setSyncParams(syncParams); videoDecoder.setCallback(decoderCallback, null); videoDecoder.start(); }MediaCodec.Callback decoderCallback = new MediaCodec.Callback() { @Override public void onInputBufferAvailable(MediaCodec codec, int index) { if (index > = 0) { ByteBuffer byteBuffer = codec.getInputBuffer(index); int sampleSize = mediaExtractor.readSampleData(byteBuffer, 0); Log.d(LOG_TAG, "SampleSize: " + sampleSize); if (sampleSize < 0) { //we're at end of file so submit EOS to the decoder input Log.d(LOG_TAG, "Video Decoder input EOS reached"); codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); } else { long sampleTime = mediaExtractor.getSampleTime(); codec.queueInputBuffer(index, 0, sampleSize, sampleTime, 0); mediaExtractor.advance(); } } }@Override public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) { Log.d(LOG_TAG, "Rendering with preso time: " + info.presentationTimeUs); codec.releaseOutputBuffer(index, info.presentationTimeUs); } };

}
上面的任务是从主线程开始使用的
VideoDecoderTask decoderTask = new VideoDecoderTask(clipPath, newSurface(surface)); Thread thread = new Thread(decoderTask); thread.start();

其中surface来自TextureView
【使用MediaSync的Android应用在播放视频时冻结】我从mediasync生成的消息中得到的有根据的猜测是,由于某种原因,onOutputBufferAvailable中返回的缓冲区不会被释放回来。我需要解决这个问题?
顺便说一句,我在https://developer.android.com/preview/download.html#images的Nexus9运行开发版M上运行它
答案我发现了一个问题。
codec.releaseOutputBuffer(index,info.presentationTimeUs);
codec.releaseOutputBuffer(index,1000 * info.presentationTimeUs);
请参阅下面的MediaSync示例。
https://github.com/skysign/MediaSyncExample
另一答案如果我用SurfaceView替换输出TextureView,视频播放似乎工作正常。
虽然这解决了我的问题,但我不明白为什么使用SurfaceTexture创建的曲面和从SurfaceHolder.Per获得的曲面之间存在差异http://developer.android.com/reference/android/graphics/SurfaceTexture.html“从SurfaceTexture创建的曲面可以用作输出目标android.hardware.camera2,MediaCodec,MediaPlayer“。这几乎就是我在上面使用MediaSync / MEdiaCodec和TextureView作为输出表面的例子中所做的

    推荐阅读