繁体   English   中英

如何使用mediacodec在android中使用软件编解码器

[英]how to use software codec in android using mediacodec

我希望使用mediacodec软件编解码器将yuv数据编码为h264。

我使用谷歌软件编码器OMX.google.h264.encoder

当我使用硬件编码器[OMX.qcom.video.encoder.avc]那时它工作,但当我使用软件编码器[OMX.google.h264.encoder]它不编码file.it将给出错误[见日志]。

什么是我无法识别的问题。

资源 :

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
    }

但是我得到了这个错误。

记录:

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)

SW编码器OMX.google.h264.encoder目前非常有限(编辑:在Android 5.0上),接近无法使用。

此编码器不允许使用不是16的倍数的分辨率。在您的情况下,1920x1080,高度1080不能均匀地分割为16,因此对于此编码器是不可接受的。 (请参阅https://android-review.googlesource.com/38904以尝试解决此问题。)

如果您将其更改为1088,则16的倍数不会成为问题,但编码器也不允许您使用任何高于352x288的分辨率(请参阅https:// android-review。 googlesource.com/82133 )。

最后,在较旧的Android版本(5.0之前)上,它也以稍微不同的格式输出(缺少启动码,请参阅https://android-review.googlesource.com/42321 ),这意味着您必须手动添加每个输出数据包开始时的启动码能够在某些地方使用它们( MediaMuxer可能已经按MediaMuxer处理它,但主要是偶然的)。

在当前的AOSP主机中(也就是说,可能在下一个主要版本中,除非已经完成并且此类更改尚未包含在内),编码器已被更强大的编码器取代,但对于现有版本,则有除了在您的应用程序中捆绑更好的SW编码器之外,您无能为力。

编辑:今天发布的Android M预览确实包含新的SW编码器,它应该适用于此用例。

Edit2:新的编码器包含在Android 6.0版本(M)中,所以从那时起,它应该可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM