
設定相機
// 打開攝像頭并將展示方向旋轉90度
camera = Camera.open(1);
camera.setDisplayOrientation(90);
//設定相機回呼資料格式
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(ImageFormat.NV21);
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
for (Camera.Size size : supportedPreviewSizes) {
if (size.width == 640 && size.height == 480) {
previewSize = size;
break;
}
}
parameters.setPictureSize(previewSize.width, previewSize.height);
camera.setParameters(parameters);
//設定資料回呼監聽器
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//Log.e(TAG, "資料長度 = " + data.length);
try {
Encoder.getInstance().putYUVData(data);
} catch (Exception e) {
e.printStackTrace();
}
}
});
初始化編碼器
[code=java][/code]
m_width = width;
m_height = height;
m_framerate = VFPS;
MediaFormat mediaFormat = MediaFormat.createVideoFormat(VCODEC, width, height);
colorFormat = ColorUtil.getColor2(ColorUtil.getMediaCodecInfoByType(VCODEC));
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUV420SemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, VFPS);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 10000000);
mediaFormat.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 20000000);
mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
try {
mediaCodec = MediaCodec.createEncoderByType("video/avc");
} catch (IOException e) {
e.printStackTrace();
}
//配置編碼器引數
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
//啟動編碼器
mediaCodec.start();
編碼
public void startEncoderThread() {
YuvEngineWrap.newInstance().startYuvEngine();
encoderThread = new Thread(new Runnable() {
@Override
public void run() {
isRuning = true;
byte[] input = null;
long pts = 0;
long generateIndex = 0;
while (isRuning) {
//訪問MainActivity用來緩沖待解碼資料的佇列
if (YUVQueue.size() > 0) {
//從緩沖佇列中取出一幀
input = YUVQueue.poll();
byte[] yuv420sp = new byte[m_width * m_height * 3 / 2];
YuvEngineWrap.newInstance().Nv21ToNv12(input, yuv420sp, m_width, m_height);
//旋轉方向
input = YUV420spRotateUtils.rotateYUVDegree270(yuv420sp, m_height, m_width);
}
if (input != null) {
try {
//編碼器輸入緩沖區
ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
//編碼器輸出緩沖區
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
pts = computePresentationTime(generateIndex);
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
//把轉換后的YUV420格式的視頻幀放到編碼器輸入緩沖區中
inputBuffer.put(input);
mediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, pts, 0);
generateIndex += 1;
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
if (bufferInfo.flags == BUFFER_FLAG_CODEC_CONFIG) {
configbyte = new byte[bufferInfo.size];
configbyte = outData;
} else if (bufferInfo.flags == BUFFER_FLAG_KEY_FRAME) {
byte[] keyframe = new byte[bufferInfo.size + configbyte.length];
System.arraycopy(configbyte, 0, keyframe, 0, configbyte.length);
//把編碼后的視頻幀從編碼器輸出緩沖區中拷貝出來
System.arraycopy(outData, 0, keyframe, configbyte.length, outData.length);
if (null != onMediaInfoListener)
onMediaInfoListener.pushVideoData(keyframe, true);
} else {
if (null != onMediaInfoListener)
onMediaInfoListener.pushVideoData(outData, true);
}
mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
}
} catch (Throwable t) {
t.printStackTrace();
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
encoderThread.start();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/92813.html
標籤:Android
