首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用MediaSync的安卓应用程序在播放视频时冻结

使用MediaSync的安卓应用程序在播放视频时冻结
EN

Stack Overflow用户
提问于 2015-09-23 19:00:24
回答 1查看 1.6K关注 0票数 0

我正在尝试使用新的MediaSync API来同步播放视频和音频。https://developer.android.com/reference/android/media/MediaSync.html

我让只有音频的播放器使用MediaSync工作,但是对于只播放视频的播放器,在显示5-6帧之后,我就在logcat中得到了这个

代码语言:javascript
运行
复制
I/MediaSync﹕ still waiting to release a buffer before acquire

我的视频播放器如下所示

代码语言:javascript
运行
复制
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);
    }
};

}

上面的任务将从主线程中启动,使用

代码语言:javascript
运行
复制
VideoDecoderTask decoderTask = new VideoDecoderTask(clipPath, new    Surface(surface));
        Thread thread = new Thread(decoderTask);
        thread.start();

其中曲面来自TextureView

我从消息中介异步生成的消息中得到的猜测是,由于某种原因,onOutputBufferAvailable中返回的缓冲区没有被释放。我需要什么来解决这个问题?

顺便说一下,我是在从Nexus9运行开发工具M版的https://developer.android.com/preview/download.html#images上运行的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-24 17:21:37

如果我用一个TextureView代替输出SurfaceView,视频回放似乎很好。

虽然这解决了我的问题,但我不明白为什么用SurfaceTexture创建的曲面与从SurfaceHolder.Per http://developer.android.com/reference/android/graphics/SurfaceTexture.html获得的曲面有区别“从SurfaceTexture创建的曲面可以用作android.hardware.camera2、MediaCodec、MediaPlayer的输出目的地”。这就是我在上面的示例中所做的,它使用MediaSync/MEdiaCodec和TextureView作为输出面。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32747466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档