In my i want encode yuv data into h264 using mediacodec software codec.
I use Google software 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].
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)
A codec is a hardware- or software-based process that compresses and decompresses large amounts of data. Codecs are used in applications to play and create media files for users, as well as to send media files over a network. The term is a blend of the words coder and decoder, as well as compression and decompression.
MediaCodec: MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components. It is part of the Android low-level multimedia support infrastructure. So MediaCodec handles the decoding or encoding of the video packets/buffers and is responsible for the interaction with the codec.
The SW encoder OMX.google.h264.encoder
is very limited at the moment (edit: On Android 5.0), close to being unusable.
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. (See https://android-review.googlesource.com/38904 for an attempt at fixing this.)
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 e.g. 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).
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.
Edit: The Android M preview that was released today does include the new SW encoder, which should work fine for this usecase.
Edit2: The new encoder was included in the Android 6.0 release (M), so since then, it should be usable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With