1

I am encoding a video using MediaCodec using Camera's setPreviewCallback. (I follow this example Encoding H.264 from camera with Android MediaCodec). I use the follow setting for the MediaCodec:

mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 1280, 720);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 8000000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();

My Camera setting are:

Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
parameters.setPictureSize(previewWidth, 1280);
parameters.setPreviewSize(previewWidth, 720);
parameters.setPreviewFrameRate(30);
parameters.setPreviewFpsRange(5000,30000);
mCamera.setParameters(parameters);

I got a video but there are two problems:

  1. its colors are wrong.
  2. its playing too fast.

Here is an example video

http://www.youtube.com/watch?v=I1Eg2bvrHLM&feature=youtu.be

Does any of you guys know what are the causes of this two problem? And may be tell me some ways to solve this problem because I am totally lost/confused now. thanks for reading and would appreciate any comments and opinions.

Community
  • 1
  • 1
xiaowoo
  • 2,248
  • 7
  • 34
  • 45
  • And here is a link that will show the ordering of the bytes for YUV420SemiPlanar vs YUV420Planar (http://www.symlab.org/main/documentation/reference/s3/pdk/GUID-D429672C-448D-5E91-ABA0-81680869D69E.html). I hope it can help others. – xiaowoo Nov 12 '13 at 01:38

1 Answers1

5

The YUV formats used by Camera output and MediaCodec input have their U/V planes swapped.

If you are able to move the data through a Surface you can avoid this issue; however, you lose the ability to examine the YUV data. An example of recording to a .mp4 file from a camera can be found on bigflake.

Some details about the colorspaces and how to swap them is in this answer.

There is no timestamp information in the raw H.264 elementary stream. You need to pass the timestamp through the decoder to MediaMuxer or whatever you're using to create your final output. If you don't, the player will just pick a rate, or possibly play the frames as fast as it can.

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166
  • Hi fadden, I finally solved the coloring problem. You led me to the right direction and is right that there are some color swapping work to be done. I have to swap the ordering the U and V byte in the incoming byte[] array (the one from onPreviewFrame). The only differences between my situation and http://stackoverflow.com/questions/13703596/mediacodec-and-camera-colorspaces-dont-match is that I have a COLOR_FormatYUV420SemiPlanar instead of COLOR_FormatYUV420Planar. After looking up and comparing semi-planar vs planar, I finally understand how to swap them. thanks again. – xiaowoo Nov 12 '13 at 01:35