带有MediaCodec的Android TextureView显示嘈杂的图像

问题描述

我是带MediaCodec的TextureView,它显示了从远程服务获得的实时流中H.264格式的视频流。

这是我的实现: 首先,声明变量:

    private TextureView m_surface;// View that contains the Surface Texture    
    private MediaCodec m_codec;// Media decoder
    private DecodeFramesTask m_frameTask;// AsyncTask that takes H264 frames and uses the decoder to update the Surface Texture

现在在OnCreate方法中初始化变量:

@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.help_fragment,container,false);
    
    // Get a referance to the TextureView in the UI
    m_surface = (TextureView) root.findViewById(R.id.textureView);
    // Add this class as a call back so we can catch the events from the Surface Texture
    m_surface.setSurfaceTextureListener(this);

    return root;
}

这是其余的代码:

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,int width,int height) {

    // Create the format settinsg for the MediaCodec
    MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC,1280,720);
    // Set the buffer size
    format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE,100000);
    format.setInteger(MediaFormat.KEY_FRAME_RATE,30);

    try {
        // Get an instance of MediaCodec and give it its Mime type
        m_codec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
        // Configure the Codec
        m_codec.configure(format,new Surface(m_surface.getSurfaceTexture()),null,0);
        // Start the codec
        m_codec.start();
        // Create the AsyncTask to get the frames and decode them using the Codec
        m_frameTask = new DecodeFramesTask();
        m_frameTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface,int height) {

}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
    return false;
}

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {

}

private class DecodeFramesTask extends AsyncTask<String,String,String> {

    @Override
    protected String doInBackground(String... data) {
        while (!isCancelled()) {
            // Get the next frame
            byte[] frame = remoteSerice.getVideoPacket(); // getting the video packet in byte[]

            // Get the input buffer from the decoder
            int inputIndex = m_codec.dequeueInputBuffer(-1);// Pass in -1 here as in this example we don't have a playback time reference

            // If  the buffer number is valid use the buffer with that index
            if (inputIndex >= 0 && frame != null) {
                ByteBuffer buffer = m_codec.getInputBuffer(inputIndex);
                buffer.put(frame);
                // tell the decoder to process the frame
                m_codec.queueInputBuffer(inputIndex,frame.length,0);
            }

            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            int outputIndex = m_codec.dequeueOutputBuffer(info,0);
            if (outputIndex >= 0) {
                m_codec.releaseOutputBuffer(outputIndex,true);
            }
        }
        return "";
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            m_codec.stop();
            m_codec.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

@Override
public void onStop() {
    super.onStop();
    m_frameTask.cancel(true);
}

现在我在textureView上得到了一张图像,但这只是一个紫色的图像,有时会变为另一个图像。

在实现它的方式上我缺少什么吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...