Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java android-设置mediacodec的显示时间_Java_Android_Encode_Android Mediacodec_Mediamuxer - Fatal编程技术网

Java android-设置mediacodec的显示时间

Java android-设置mediacodec的显示时间,java,android,encode,android-mediacodec,mediamuxer,Java,Android,Encode,Android Mediacodec,Mediamuxer,为了创建视频,我使用了下面的代码将原始数据编码到h264,编码非常好,但视频播放速度太快。似乎演示时间有问题。当记录开始时,我设置“tstart”的值,并为每个帧计算当前时间与tstart的差值,并将其传递给queueinputbuffer,但没有任何更改。哪一部分有问题?我知道在安卓4.3中,我可以将surface传递给mediacodec,但我想支持安卓4.1。提前谢谢 public void onPreviewFrame(final byte[] bytes, Camera camera

为了创建视频,我使用了下面的代码将原始数据编码到h264,编码非常好,但视频播放速度太快。似乎演示时间有问题。当记录开始时,我设置“tstart”的值,并为每个帧计算当前时间与tstart的差值,并将其传递给queueinputbuffer,但没有任何更改。哪一部分有问题?我知道在安卓4.3中,我可以将surface传递给mediacodec,但我想支持安卓4.1。提前谢谢

 public void onPreviewFrame(final byte[] bytes, Camera camera) {
                    if (recording == true) {
                        long time = System.nanoTime();
                        time -= tstart;
                        if(mThread.isAlive()&&recording == true) {
                            encode(bytes, time );

                        }

                    }
 }

private synchronized void encode(byte[] dataInput,long time)
{
    byte[] data=new byte[dataInput.length];
    NV21toYUV420Planar(dataInput,data,640,480);

    inputBuffers = mMediaCodec.getInputBuffers();// here changes
    outputBuffers = mMediaCodec.getOutputBuffers();

    int inputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);

    if (inputBufferIndex >= 0) {
        ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
        inputBuffer.clear();
        inputBuffer.put(data);
        time/=1000;
        mMediaCodec.queueInputBuffer(inputBufferIndex, 0, data.length, time, 0);

    } else {
        return;
    }

    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
    Log.i("tag", "outputBufferIndex-->" + outputBufferIndex);
    do {
        if (outputBufferIndex >= 0) {
            ByteBuffer outBuffer = outputBuffers[outputBufferIndex];
            byte[] outData = new byte[bufferInfo.size];
            outBuffer.get(outData);
            try {
                if (bufferInfo.offset != 0) {
                    fos.write(outData, bufferInfo.offset, outData.length
                            - bufferInfo.offset);
                } else {
                    fos.write(outData, 0, outData.length);
                }
                fos.flush();
                Log.i("camera", "out data -- > " + outData.length);
                mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
                outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo,
                        0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            outputBuffers = mMediaCodec.getOutputBuffers();
        } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            MediaFormat format = mMediaCodec.getOutputFormat();
        }
    } while (outputBufferIndex >= 0);
}

您的问题是,您根本没有将输出帧写入实际存储任何时间戳的容器中。您正在编写一个普通的H264文件,它只包含原始编码帧,没有索引,没有时间戳,没有音频,没有其他内容


为了获得文件的正确时间戳,您需要使用
MediaMuxer
(见4.3)或类似的第三方库(如libavformat或类似工具)将编码包写入文件。输出数据包的时间戳位于
bufferInfo.presentationTime
if(outputBufferIndex>=0)中{
子句,您根本不使用它-您基本上是在扔掉时间戳。

那么什么是presentationTimeUs,它是queueinputbuffer函数的第四个参数?即输入帧的显示时间。在大多数情况下,它实际上不包括在编码数据中,它只与编码帧一起带来,所以您知道编码数据包对应的时间戳。将编码数据包写入文件时,需要将其(
bufferInfo.presentationTimeUs
)提供给文件(将其提供给MediaMuxer API或用于写入视频文件的其他库).@SajadNorouzi数据包不必按照它们进入编码器的顺序从编码器中出来。因此,如果时间戳没有传递,您可能无法将时间戳与输出数据包匹配。