[英]how to use software codec in android using mediacodec
In my i want encode yuv data into h264 using mediacodec software codec. 我希望使用mediacodec软件编解码器将yuv数据编码为h264。
I use Google software encoder OMX.google.h264.encoder 我使用谷歌软件编码器OMX.google.h264.encoder
when i use hardware encoder[OMX.qcom.video.encoder.avc] that time it work but when i use software encoder[OMX.google.h264.encoder] it not encode file.it will give error [see in log]. 当我使用硬件编码器[OMX.qcom.video.encoder.avc]那时它工作,但当我使用软件编码器[OMX.google.h264.encoder]它不编码file.it将给出错误[见日志]。
what is problem i couldn't identify. 什么是我无法识别的问题。
Source : 资源 :
mediaCodec = MediaCodec.createByCodecName("OMX.google.h264.encoder");
//mediaCodec = MediaCodec.createByCodecName(codecInfo.getName());
Log.i(TAG,"codec name : "+ mediaCodec.getName());
int mBitrate = (int) ((MainActivity.mHeight * MainActivity.mWidth * MainActivity.frameRate)*2*0.07);
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc",MainActivity.mWidth,MainActivity.mHeight);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE,mBitrate);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, MainActivity.frameRate);
// mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 320*240);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,colorFormat);
//mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,MediaCodecInfo.CodecProfileLevel.AVCLevel12);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,1);
try{
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
Log.i(TAG,"H264 Encoder init success");
}catch(IllegalArgumentException e)
{
e.printStackTrace();
}catch (IllegalStateException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();// TODO: handle exception
}
But i getting this error. 但是我得到了这个错误。
Log : 记录:
I/H264Encoder(7772): outputStream initialized
I/OMXClient(7772): Using client-side OMX mux.
I/H264Encoder(7772): found colorFormat: 21
I/OMXClient(7772): Using client-side OMX mux.
E/OMXMaster(7772): A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
I/SoftAVCEncoder(7772): Construct SoftAVCEncoder
I/H264Encoder(7772): codec name : OMX.google.h264.encoder
E/SoftAVCEncoder(7772): internalSetParameter: StoreMetadataInBuffersParams.nPortIndex not zero!
E/OMXNodeInstance(7772): OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x80001001
E/ACodec(7772): [OMX.google.h264.encoder] storeMetaDataInBuffers (output) failed w/ err -2147483648
I/ACodec(7772): setupVideoEncoder succeeded
I/H264Encoder(7772): H264 Encoder init success
E/SoftAVCEncoder(7772): Video frame size 1920x1080 must be a multiple of 16
E/SoftAVCEncoder(7772): Failed to initialized encoder params
E/ACodec(7772): [OMX.google.h264.encoder] ERROR(0x80001001)
E/MediaCodec(7772): Codec reported an error. (omx error 0x80001001, internalError -2147483648)
W/System.err(7772): java.lang.IllegalStateException
W/System.err(7772): at android.media.MediaCodec.getBuffers(Native Method)
W/System.err(7772): at android.media.MediaCodec.getInputBuffers(MediaCodec.java:542)
W/System.err(7772): at com.ei.encodertest.H264Encoder.offerEncoder(H264Encoder.java:170)
W/System.err(7772): at com.ei.encodertest.MainActivity$ReadRawFileTask.doInBackground(MainActivity.java:113)
W/System.err(7772): at com.ei.encodertest.MainActivity$ReadRawFileTask.doInBackground(MainActivity.java:1)
W/System.err(7772): at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err(7772): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err(7772): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err(7772): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err(7772): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err(7772): at java.lang.Thread.run(Thread.java:841)
The SW encoder OMX.google.h264.encoder
is very limited at the moment (edit: On Android 5.0), close to being unusable. SW编码器
OMX.google.h264.encoder
目前非常有限(编辑:在Android 5.0上),接近无法使用。
This encoder doesn't allow using resolutions that aren't a multiple of 16. In your case, 1920x1080, the height 1080 isn't evenly dividable by 16, and thus isn't acceptable for this encoder. 此编码器不允许使用不是16的倍数的分辨率。在您的情况下,1920x1080,高度1080不能均匀地分割为16,因此对于此编码器是不可接受的。 (See https://android-review.googlesource.com/38904 for an attempt at fixing this.)
(请参阅https://android-review.googlesource.com/38904以尝试解决此问题。)
If you'd change it into 1088, the multiple-of-16 wouldn't be an issue, but the encoder also won't allow you to use it with any resolution above 352x288 (see eg https://android-review.googlesource.com/82133 ). 如果您将其更改为1088,则16的倍数不会成为问题,但编码器也不允许您使用任何高于352x288的分辨率(请参阅https:// android-review。 googlesource.com/82133 )。
Finally, on older Android versions (prior to 5.0), it also did output in a slightly different format (missing startcodes, see https://android-review.googlesource.com/42321 ), which meant that you would have to manually add startcodes at the start of each output packet to be able to use them in certain places (the MediaMuxer
might have handled it as it was, though, mostly by chance). 最后,在较旧的Android版本(5.0之前)上,它也以稍微不同的格式输出(缺少启动码,请参阅https://android-review.googlesource.com/42321 ),这意味着您必须手动添加每个输出数据包开始时的启动码能够在某些地方使用它们(
MediaMuxer
可能已经按MediaMuxer
处理它,但主要是偶然的)。
In the current AOSP master (that is, maybe in the next major release, unless that already is being finalized and this change hasn't been included there), the encoder has been replaced with a more capable one, but for existing releases, there's not much you can do other than bundling a better SW encoder within your app. 在当前的AOSP主机中(也就是说,可能在下一个主要版本中,除非已经完成并且此类更改尚未包含在内),编码器已被更强大的编码器取代,但对于现有版本,则有除了在您的应用程序中捆绑更好的SW编码器之外,您无能为力。
Edit: The Android M preview that was released today does include the new SW encoder, which should work fine for this usecase. 编辑:今天发布的Android M预览确实包含新的SW编码器,它应该适用于此用例。
Edit2: The new encoder was included in the Android 6.0 release (M), so since then, it should be usable. Edit2:新的编码器包含在Android 6.0版本(M)中,所以从那时起,它应该可用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.