本文介绍了使用Media codec.getOutputFormat()为一间codeR中的Andr​​oid 4.1 / 4.2设备的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用媒体codec到EN code帧(通过相机或德codeR)到视频。
当处理由dequeueOutputBuffer()的EN codeR输出,我期望得到回报指数=媒体codec.INFO_OUTPUT_FORMAT_CHANGED,这样我就可以调用getOutputFormat()来获取连接codeR输出格式为输入目前使用的ffmpeg的合并器。

I'm trying to use MediaCodec to encode frames (either by camera or decoder) into a video.When processing the encoder output by dequeueOutputBuffer(), I expect to receive the return index = MediaCodec.INFO_OUTPUT_FORMAT_CHANGED, so I can call getOutputFormat() to get the encoder output format as the input of the currently used ffmpeg muxer.

我已经测试了一些垫/电话设备与Android版本4.1〜4.3。所有的人都至少有一个硬件视频AVC EN codeR,并在测试时使用。与4.3版本的装置中,连接codeR给媒体codec.INFO_OUTPUT_FORMAT_CHANGED如预期写入烯$ C $光盘数据之前,从getOutputFormat返回的输出格式()可由复用器正确使用。上与4.2.2或更低的设备中,连接codeR从不给媒体codec.INFO_OUTPUT_FORMAT_CHANGED而它仍然可以输出连接$ C $光盘的基本流,但是复用器可以不知道确切的输出格式。

I have tested some pad/phone devices with Android version 4.1~4.3. All of them have at least one hardware video AVC encoder and is used in the test. On the devices with version 4.3, the encoder gives MediaCodec.INFO_OUTPUT_FORMAT_CHANGED before writing the encoded data as expected, and the output format returned from getOutputFormat() can be used by the muxer correctly. On the devices with 4.2.2 or lower, the encoder never gives MediaCodec.INFO_OUTPUT_FORMAT_CHANGED while it can still output the encoded elementary stream, but the muxer cannot know the exact output format.

我要问以下几个问题:


  1. 的是否带codeR行为(给媒体codec.INFO_OUTPUT_FORMAT_CHANGED或不连接允许输出codeD数据之前)取决于Android的API级别或单个设备上的筹码?

  2. 如果在连接​​codeR写入媒体codec.INFO_OUTPUT_FORMAT_CHANGED出现之前的数据,有没有什么办法让EN codeD数据的输出格式?

  3. 的EN codeR还是输出codeC配置数据(与国旗媒体codec.BUFFER_FLAG_ codeC_CONFIG)的EN codeD数据之前的设备。它主要用于配置脱codeR,但我可以用codeC配置数据得出的输出格式?

我曾尝试这些解决方案得到的输出格式,但失败:

I have tried these solutions to get the output format but failed:


  • 整体卫浴code过程中调用getOutputFormat()频繁。但是,所有的人都扔不IllegalStateException异常媒体codec.INFO_OUTPUT_FORMAT_CHANGED的外观。

  • 使用初始MediaFormat使用在开始时配置的EN codeR,像例如:

  • Call getOutputFormat() frequently during the whole encode process. However, all of them throw IllegalStateException without the appearance of MediaCodec.INFO_OUTPUT_FORMAT_CHANGED.
  • Use the initial MediaFormat use to config the encoder at the beginning, like the example:

m_init_encode_format = MediaFormat.createVideoFormat(m_encode_video_mime, m_frame_width, m_frame_height);
int encode_bit_rate = 3000000;
int encode_frame_rate = 15;
int encode_iframe_interval = 2;

m_init_encode_format.setInteger(MediaFormat.KEY_COLOR_FORMAT, m_encode_color_format);
m_init_encode_format.setInteger(MediaFormat.KEY_BIT_RATE, encode_bit_rate);
m_init_encode_format.setInteger(MediaFormat.KEY_FRAME_RATE, encode_frame_rate);
m_init_encode_format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, encode_iframe_interval);

m_encoder = MediaCodec.createByCodecName(m_video_encoder_codec_info.getName());
m_encoder.configure(m_init_encode_format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

// Assume m_init_encode_format is the output format of the encoder

但它失败,因为连接codeR的输出格式还是从最初的一家改变了。

However it fails since the output format of the encoder is still "changed" from the initial one.

请帮我实现的连接codeR的行为,如果有任何解决方案,查询的输出格式,如果需要的媒体codec.INFO_OUTPUT_FORMAT_CHANGED丢失。

Please help me to realize the behavior of an encoder, and if there is any solution to query the output format if the required MediaCodec.INFO_OUTPUT_FORMAT_CHANGED is missing.

通过比较输出格式和codeC配置数据,丢失的字段是CSD-0,CSD-1,并用值= 1869968451一个什么字段。
(我不明白什么字段中。这似乎是一个常量,不是必需的。谁能告诉我它的意思吗?)

By comparing the output format and the codec config data, the missing fields are csd-0, csd-1, and a "what" field with value = 1869968451.(I do not understand the "what" field. It seems to be a constant and is not required. Can anyone tell me about its meaning?)

如果我解析codeC的配置数据作为CSD-1场(最后8个字节)和CSD-0场(其余字节),似乎是流合并器能够正常工作,输出的视频上播放所有的测试设备。
(但我要问:这是8个字​​节的假设是正确的,或者对分析数据更可靠的方式)

If I parse the codec config data as the csd-1 field (last 8 bytes) and csd-0 field (remaining bytes), it seems that the muxer can work correctly and output a video playable on all of the testing devices.(But I want to ask: is this 8-byte assumption correct, or there is more reliable way to parse the data?)

不过,我得到了)另外一个问题,如果我再次去code。通过Android的媒体codeC视频中,BufferInfo。presentationTimeUs值由dequeueOutputBuffer(得到的是0大多数去$ C的$ CD帧。只有最后几帧有正确的时间。采样时间由MediaExtractor.getSampleTime得到()是正确的,正是我设置为EN codeR /合并器的价值,但去codeD帧时间是没有的。此问题只发生在4.2.2或更低的设备。

However, I got another problem that If I decode the video by Android MediaCodec again, the BufferInfo.presentationTimeUs value get by dequeueOutputBuffer() is 0 for most of the decoded frames. Only the last few frames has correct time. The sample time get by MediaExtractor.getSampleTime() is correct and exactly the value I set to the encoder/muxer, but the decoded frame time is not. This issue only happen on 4.2.2 or lower device.

令人奇怪的是帧时间不正确,但视频可以在设备上正确速度播放。 (与大部分4.2.2或更低我测试过的设备只有1个视频AVC德codeR)。我是否需要设置,可能会影响presentation时间等领域?

It is strange that the frame time is incorrect but the video can be playback in correct speed on the device. (Most of the devices with 4.2.2 or lower I've tested has only 1 Video AVC decoder.) Do I need to set other fields that may affect the presentation time?

推荐答案

的行为媒体codeC 连接codeRS在Android 4.3的改变,以适应引进了 MediaMuxer 类的。在Android 4.3的,你永远从EN codeR收到 INFO_OUTPUT_FORMAT_CHANGED 。在previous的版本中,你不会的。 (我已经更新href=\"http://bigflake.com/media$c$cc/#q9\" rel=\"nofollow\">相关FAQ条目的

The behavior of MediaCodec encoders was changed in Android 4.3 to accommodate the introduction of the MediaMuxer class. In Android 4.3, you will always receive INFO_OUTPUT_FORMAT_CHANGED from the encoder. In previous releases, you will not. (I've updated the relevant FAQ entry.)

有没有办法查询的EN codeR的 MediaFormat

There is no way to query the encoder for the MediaFormat.

我没有使用基于ffmpeg的,合并器,所以我不知道它需要什么样的信息。如果它寻找CSD-0 / CSD-1键,可以提取那些从 codeC_CONFIG 包(我想你要解析的SPS / PPS值出来并将它们放置在分开的键)。检查4.3设备上的 MediaFormat 的内容将告诉你哪些领域你缺乏。

I haven't used an ffmpeg-based muxer, so I'm not sure what information it needs. If it's looking for the csd-0 / csd-1 keys, you can extract those from the CODEC_CONFIG packet (I think you have to parse the SPS / PPS values out and place them in the separate keys). Examining the contents of the MediaFormat on a 4.3 device will show you which fields you're lacking.

这篇关于使用Media codec.getOutputFormat()为一间codeR中的Andr​​oid 4.1 / 4.2设备的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 09:03