Android MediaCodec:编码falis,因为没有用于视频轨道的同步帧

时间:2014-03-03 05:20:58

标签: android mpeg-4 mediacodec

我打算将视频文件转换为另一个具有不同比特率,fps等的视频文件。

最重要的是我按照中的例子进行操作 http://bigflake.com/mediacodec

但是,日志显示视频轨道没有同步帧错误:

submitted frame 5 to dec, size=47398
no output from encoder available
decoder output format changed: {height=1080, what=1869968451, color-format=2141391875, slice-height=1088, crop-left=0, width=1920, crop-bottom=1079, crop-top=0, mime=video/raw, stride=1920, crop-right=1919}
no output from encoder available
surface decoder given buffer 0 (size=3137536)
awaiting frame
E/MPEG4Writer(3464): There are no sync frames for video track
W/MPEG4Writer(3464): 0-duration samples found: 1
Stopping Video track

然后程序退出。

我在线搜索。法登说 "Make sure you are passing all of the MediaCodec.BufferInfo values through to the MediaMuxer -- that's where the flags are. The sync frames will have the BUFFER_FLAG_SYNC_FRAME flag set."

但是,从http://bigflake.com/mediacodec的示例中,它使用:

outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,10); 

这似乎意味着编码器将确定使用关键帧分配哪个帧。

似乎没有关于此问题的在线相关信息。 哦,希望bigflake.com有更多与开发人员感兴趣的问题相关的示例(例如更改一个现有视频文件的格式参数)

== [更新] == 以下是我使用的一些代码:

MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
        MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE,5000000);
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE,30);
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,5); 
encoder = MediaCodec.createEncoderByType(MIME_TYPE);
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
inputSurface = new InputSurface(encoder.createInputSurface());
inputSurface.makeCurrent();
encoder.start();
...
try {
    mMuxer = new MediaMuxer(ouVideoFileName, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
} catch (IOException ioe) {
    throw new RuntimeException("MediaMuxer creation failed", ioe);
}
...
// now that we have the Magic Goodies, start the muxer
mTrackIndex = mMuxer.addTrack(newFormat);
mMuxer.start();
mMuxerStarted = true;
...
mMuxer.writeSampleData(mTrackIndex, encodedData, info_encoder);

那我在哪里将参数传递给mMuxer?我似乎已经通过了所有必需的参数。

== [更新2] == 在:

int encoderStatus = encoder.dequeueOutputBuffer(info_encoder, TIMEOUT_USEC);

我注销了info_encoder.flags:从第0帧到第5帧,flags = 0.它们不是Key Frame的标志。输入视频文件是由设备记录的短文件.mp4,并且可以正确播放。 在第5帧之后,MPEG4Write抱怨“视频轨道没有同步帧”。

== [更新3] == 顺便说一句,我发现DecodeEditEncodeTest.java和EncodeDecodeTest.java之间的编码部分是不同的。 EncodeDecodeTest.java中的编码部分包括encoder.dequeueInputBuffer,而在DecodeEditEncodeTest.java中根本没有与encoder.dequeueInputBuffer相关的行。你认为这会有问题吗?但首先,为什么两个例子中它们不同?

== [更新4] == 我将代码复制到类ExtractMpegFramesTest 然后在我的主要活动中,我有一个按钮。点击按钮后,它会调用:

// test:
ExtractMpegFramesTest mTest = new ExtractMpegFramesTest();
try {
    mTest.testExtractMpegFrames();
} catch (Throwable e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

错误:

E/ACodec(11342): [OMX.qcom.video.decoder.avc] storeMetaDataInBuffers failed w/ err -2147483648
java.lang.RuntimeException: frame wait timed out
ExtractMpegFramesTest$CodecOutputSurface.awaitNewImage(ExtractMpegFramesTest.java:496)

0 个答案:

没有答案