如何使用媒体codeC不MediaExtractor为H264 [英] How to use MediaCodec without MediaExtractor for H264

查看:612
本文介绍了如何使用媒体codeC不MediaExtractor为H264的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用媒体codeC没有MediaExtractor,我看用一个FileInputStream文件。目前它是不工作,它正显示在屏幕上的绿色加扰图像。

I need to use MediaCodec without the MediaExtractor and I'm reading the file using a FileInputStream. Currently it is not working, it is showing a greenish scrambled image on the screen.

这是整个源$ C ​​$ C:

This is the whole source code:

FileInputStream in = new FileInputStream("/sdcard/sample.ts");

String mimeType = "video/avc";
MediaCodec decoder = MediaCodec.createDecoderByType(mimeType);
MediaFormat format = MediaFormat.createVideoFormat(mimeType, 1920, 1080);

byte[] header_sps = { 0, 0, 0, 1, 103, 100, 0, 40, -84, 52, -59, 1, -32, 17, 31, 120, 11, 80, 16, 16, 31, 0, 0, 3, 3, -23, 0, 0, -22, 96, -108 };
byte[] header_pps = { 0, 0, 0, 1, 104, -18, 60, -128 };
format.setByteBuffer("csd-0", ByteBuffer.wrap(header_sps));
format.setByteBuffer("csd-1", ByteBuffer.wrap(header_pps));
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080);
format.setInteger("durationUs", 63446722);

decoder.configure(format, surface, null, 0);
decoder.start();

ByteBuffer[] inputBuffers = decoder.getInputBuffers();
ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
BufferInfo info = new BufferInfo();
boolean isEOS = false;
long startMs = System.currentTimeMillis();

while (!Thread.interrupted()) {
    if (!isEOS) {
        int inIndex = decoder.dequeueInputBuffer(1000);
        if (inIndex >= 0) {
            byte buffer2[] = new byte[18800 * 8 * 8 * 8];
            ByteBuffer buffer = inputBuffers[inIndex];
            int sampleSize;

            sampleSize = in.read(buffer2, 0, 18800 * 4);

            buffer.clear();
            buffer.put(buffer2, 0, sampleSize);
            buffer.clear();

            if (sampleSize < 0) {
                decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                isEOS = true;
            } else {
                decoder.queueInputBuffer(inIndex, 0, sampleSize, 0, 0);
            }
        }
    }

    int outIndex = decoder.dequeueOutputBuffer(info, 10000);
    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! " + info);
        break;
    default:
        ByteBuffer buffer = outputBuffers[outIndex];
        Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);

        while (info.presentationTimeUs / 1000 > System.currentTimeMillis() - startMs) {
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }
        }
        decoder.releaseOutputBuffer(outIndex, true);
        break;
    }

    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
        Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
        break;
    }
}

decoder.stop();
decoder.release();

如果我用的是MediaExtractor,一切工作正常。我通过观察MediaFormat使用MediaExtractor时,得到了SPS / PPS值。如果我删除下面的部分,没有显示在屏幕上。

If I use the MediaExtractor, everything works fine. I got the SPS/PPS values by looking at the MediaFormat when using MediaExtractor. If I remove the section below, nothing is shown on the screen.

byte[] header_sps = { 0, 0, 0, 1, 103, 100, 0, 40, -84, 52, -59, 1, -32, 17, 31, 120, 11, 80, 16, 16, 31, 0, 0, 3, 3, -23, 0, 0, -22, 96, -108 };
byte[] header_pps = { 0, 0, 0, 1, 104, -18, 60, -128 };
format.setByteBuffer("csd-0", ByteBuffer.wrap(header_sps));
format.setByteBuffer("csd-1", ByteBuffer.wrap(header_pps));
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080);
format.setInteger("durationUs", 63446722);

我很想念?我怎样才能获得SPS / PPS值编程不MediaExtractor?

What I am missing? How can I get the SPS/PPS values programatically without MediaExtractor?

推荐答案

我假设你正在阅读的原始H.264基本流,而不是一个MP4文件。

I'm assuming you're reading a raw H.264 elementary stream and not an MP4 file.

它看起来像你喂的数据固定大小的块到去codeR。这是行不通的。你需要把一个接入单元到每个缓冲区。

It looks like you're feeding fixed-size blocks of data to the decoder. That doesn't work. You need to put a single access unit into each buffer.

这篇关于如何使用媒体codeC不MediaExtractor为H264的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆