Android Camera Capture using FFmpeg
android, android-camera, ffmpeg
Solution
Kinda got it working perfectly... The mistake that seemed to be happenin' was related to the `vcodec` of the image stream. Seems that ffmpeg has no provision to decode `NV21` format images or image stream. For that had to convert the `NV21` format preview frame to `JPEG` and as the images had to streamed in real time to the `ffmpeg` process ,the conversion had to be `On the Fly`. The closest reliable solution for `On the Fly` conversion to `JPEG` was as follows :
public void onPreviewFrame(byte[] data, Camera camera)
{
if(isFirstFrame)
{
Camera.Parameters cameraParam = camera.getParameters();
Camera.Size previewSize = cameraParam.getPreviewSize();
previewFormat = cameraParam.getPreviewFormat();
frameWidth = previewSize.width;
frameHeight = previewSize.height;
frameRect = new Rect(0, 0, frameWidth, frameHeight);
isFirstFrame = false;
}
previewImage = new YuvImage(data, previewFormat, frameWidth, frameHeight, null);
if(previewImage.compressToJpeg(frameRect, 50, processIn))
Log.d(TAG, "Data : " + data.length);
previewImage = null;
camera.addCallbackBuffer(new byte[bufferSize]);
}
And the `ffmpeg` command used was :
ffmpeg -f image2pipe -vcodec mjpeg -i - -f flv -vcodec libx264 out.flv
Problem
Am tryin' to take the preview frame generated by the android camera and pass the `data[]` to ffmpeg input pipe to generate a flv video. The command that I used was : ``` ffmpeg -f image2pipe -i pipe: -f flv -vcodec libx264 out.flv ``` I've also tried to force the input format to `yuv4mpegpipe` and `rawvideo` but with no success... The default format of the preview frame generated by android-camera is `NV21`. The way am invokin' ffmpeg is through the `Process API` and writing the preview frames `data[]` to the process' `stdin`... The `onPreviewFrame()` definition is as follows : ``` public void onPreviewFrame(byte[] data, Camera camera) { try { processIn.write(data); } catch(Exception e) { Log.e(TAG, FUNCTION + " : " + e.getMessage()); } camera.addCallbackBuffer(new byte[bufferSize]); } ``` `processIn` is connected to the `ffmpeg` process `stdin` and `buffersize` is computed based on the documentation provided for `addCallbackBuffer()`. Is there something that am doin' wrong...? Thanks...