博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
How to use Android MediaCodec encode Camera data(YUV420sp)
阅读量:4050 次
发布时间:2019-05-25

本文共 6285 字,大约阅读时间需要 20 分钟。

7
4

Thank you for your focus! I want to use Android MediaCodec APIs to encode the video frame which aquired from Camera, unfortunately, I have not success to do that! I still not familiar with the MediaCodec API。 The follow is my codes,I need your help to figure out what I should do.

1、The Camera setting:

Parameters parameters = mCamera.getParameters();        parameters.setPreviewFormat(ImageFormat.NV21);        parameters.setPreviewSize(320, 240);        mCamera.setParameters(parameters);

2、Set the encoder:

private void initCodec()    {
try {
fos = new FileOutputStream(mVideoFile, false); } catch (FileNotFoundException e) {
e.printStackTrace(); } mMediaCodec = MediaCodec.createEncoderByType("video/avc"); MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 320, 240); mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000); mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15); mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar); mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5); mMediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mMediaCodec.start(); inputBuffers = mMediaCodec.getInputBuffers(); outputBuffers = mMediaCodec.getOutputBuffers(); } private void encode(byte[] data) {
int inputBufferIndex = mMediaCodec.dequeueInputBuffer(0); if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; inputBuffer.clear(); inputBuffer.put(data); mMediaCodec.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0); } else {
return; } MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0); Log.i(TAG, "outputBufferIndex-->" + outputBufferIndex); do {
if (outputBufferIndex >= 0) {
ByteBuffer outBuffer = outputBuffers[outputBufferIndex]; System.out.println("buffer info-->" + bufferInfo.offset + "--" + bufferInfo.size + "--" + bufferInfo.flags + "--" + bufferInfo.presentationTimeUs); byte[] outData = new byte[bufferInfo.size]; outBuffer.get(outData); try {
if (bufferInfo.offset != 0) {
fos.write(outData, bufferInfo.offset, outData.length - bufferInfo.offset); } else {
fos.write(outData, 0, outData.length); } fos.flush(); Log.i(TAG, "out data -- > " + outData.length); mMediaCodec.releaseOutputBuffer(outputBufferIndex, false); outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0); } catch (IOException e) {
e.printStackTrace(); } } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = mMediaCodec.getOutputBuffers(); } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat format = mMediaCodec.getOutputFormat(); } } while (outputBufferIndex >= 0); }

I guess the problem occurred in the encoder method,the method will be used in the Camera Preview Callback ,like this

initCodec();                //mCamera.setPreviewCallback(new MyPreviewCallback());                mCamera.setPreviewCallback(new PreviewCallback()                {
@Override public void onPreviewFrame(byte[] data, Camera camera) {
encode(data); } });

I just have no idea how to do it correctly with the MediaCodec API.Can you give me some advice or links about it?

Thank you!

 

2 Answers

5
accepted

I have solved the problem.As follows:

private synchronized void encode(byte[] data){
inputBuffers = mMediaCodec.getInputBuffers();// here changes outputBuffers = mMediaCodec.getOutputBuffers(); int inputBufferIndex = mMediaCodec.dequeueInputBuffer(-1); Log.i(TAG, "inputBufferIndex-->" + inputBufferIndex); //......

And next,you will find your encoded video color is not right, for more information,please go to here

 
 
i got this error.how to solve this pblm....java.lang.NoClassDefFoundError: android.media.MediaCodec error point out this line : mMediaCodec = MediaCodec.createEncoderByType("video/avc"); –    
 
 
@Aravi It seems that you try to use MediaCodec on Android with API < 16 –    
2

The YUV420 formats output by the camera are incompatible with the formats accepted by the MediaCodec AVC encoder. In the best case, it's essentially NV12 vs. NV21 (U and V planes are reversed), requiring a manual reordering. In the worst case, as of Android 4.2, the encoder input format may be device-specific.

You're better off using  to connect the camera hardware to the encoder.

Update: It's now possible to pass the camera's Surface preview to MediaCodec, instead of using the YUV data in the ByteBuffer. This is faster and more portable. See the CameraToMpegTest sample.

 
 
Thank you for your help.I have recorded a video file,but the file data is not correct.The starting data is right,they are h.264 frame data,but about three frames later ,h.264 frame data are all filled with 0.May be the file buffer is wrong,I think,but it can not be 0 –    

转载地址:http://cbici.baihongyu.com/

你可能感兴趣的文章
IOS 第三方库介绍
查看>>
iPhone架构xmpp聊天工具 -xmpp协议初识《一》
查看>>
iOS提交后申请加急审核
查看>>
iOS7单元测试
查看>>
ios framework 通用库的制作
查看>>
出现( linker command failed with exit code 1)错误总结
查看>>
iOS开发中一些常见的并行处理
查看>>
iOS获取手机的Mac地址
查看>>
ios7.1发布企业证书测试包的问题
查看>>
如何自定义iOS中的控件
查看>>
iOS 开发百问
查看>>
Mac环境下svn的使用
查看>>
github简单使用教程
查看>>
如何高效利用GitHub
查看>>
GitHub详细教程
查看>>
Swift概览
查看>>
iOS系统方法进行AES对称加密
查看>>
程序内下载App,不用跳转到AppStore
查看>>
iOS应用崩溃日志分析
查看>>
获取手机系统大小、可用空间大小,设备可用内存及当前应用所占内存等
查看>>