android-解码原始h264视频流

时间:2018-12-28 17:14:27

标签: android stream h.264

我编写了一个简单的类,该类应该通过UDP套接字接收H264原始流,并将其馈送到MediaCodec,以便我可以解码帧并将其呈现到UI(TextureView表面)上。

这是代码

public class StreamReceiver implements Runnable 
{
private MyActivity activity;
private MediaCodec decoder;
private DatagramSocket socket;

public StreamReceiver(MyActivity activity, Surface surface)
{
    this.activity = activity;
    decoder = MediaCodec.createDecoderByType("video/avc");
    MediaFormat format = MediaFormat.createVideoFormat("video/avc", 1024, 768);
    decoder.configure(format, surface, null, 0);
    decoder.start();
    try
    {
        socket = new DatagramSocket(null);
        socket.setReuseAddress(true);
        socket.bind(new InetSocketAddress(22122));
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

}

@Override
public void run() 
{
    BufferInfo info = new BufferInfo();

    byte[] data = new byte[65535];
    while (true) 
    {

        DatagramPacket pkt = new DatagramPacket(data, data.length);
        try 
        {
            socket.receive(pkt);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int inputIndex = decoder.dequeueInputBuffer(-1);
        ByteBuffer inputBuffer = decoder.getInputBuffers()[inputIndex];
        if (inputIndex >= 0) 
        {

            inputBuffer.put(data, 0, pkt.getLength());
            decoder.queueInputBuffer(inputIndex, 0, pkt.getLength(), 0, 0);
        }

        int outIndex = decoder.dequeueOutputBuffer(info, 0);

        switch (outIndex)
        {
        case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
            Log.d("R", "INFO_OUTPUT_FORMAT_CHANGED format : " + decoder.getOutputFormat());
            break;

        case MediaCodec.INFO_TRY_AGAIN_LATER:
            Log.d("R", "INFO_TRY_AGAIN_LATER");
            break;

        case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
            Log.d("R", "INFO_OUTPUT_BUFFERS_CHANGED");
            break;

        default:
            Log.d("R", "Rendering");
            decoder.releaseOutputBuffer(outIndex, true);
            try 
            {
                Thread.sleep(40);
            } 
            catch (InterruptedException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            break;
        }

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

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

}

最终结果是渲染了第一帧,但是图像的某些区域被弄乱了。随之而来的帧不会被渲染,但是上面的代码中没有抛出异常。 我缺少什么来渲染视频?

如果需要sps和pps值,我将很乐意为您解释如何制作它们。我没有访问它们的权限,只是原始的h264提要,但是如果将其转储到文件中并转换为MP4会生成有效的视频,那么我认为没有它们也可以生存。

0 个答案:

没有答案