攝影機預覽實作 - android.hardware.camera2  加入錄影功能. 使用 MediaCodec 與 MediaMuxer 實作錄影功能.

MediaCodec 將輸入影像編碼, MediaMuxer 將編碼後資料寫入檔案.

<<建立 MediaCodec 與 MediaMuxer>>

將 MediaCodec 輸入影像格式設定為 COLOR_FormatSurface 並呼叫 MediaCodec.createInputSurface() 建立 Surface.

 
final int COLOR_FORMAT = CodecCapabilities.COLOR_FormatSurface;

public
Surface init() {
// Set up encode format
MediaFormat encodeFormat = MediaFormat.createVideoFormat(MINE_TYPE, WIDTH, HEIGHT);
encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FORMAT);
encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL);
encodeFormat.setInteger(MediaFormat.KEY_CAPTURE_RATE, CAPTURE_RATE);
// KEY_REPEAT_PREVIOUS_FRAME_AFTER is for Surface-Input mode. See createInputSurface().
encodeFormat.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, REPEAT_PREVIOUS_FRAME_AFTER);

// Create encoder and input surface
try {
encoder = MediaCodec.createEncoderByType(MINE_TYPE);
} catch (IOException e) {
e.printStackTrace();
}
encoder.configure(encodeFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
inputSurface = encoder.createInputSurface();

// Create MediaMuxer for write encoded data to file
try {
mediaMuxer = new MediaMuxer(MUXER_OUTPUT_FILE, MUXER_OUTPUT_FORMAT);
} catch (IOException e) {
e.printStackTrace();
}
return inputSurface;
}

 

<<將 input surface 加入預覽輸出目標>>

使用 addTarget() 預覽輸出設定為 GLSurafceView 的 previewSurafce 與 MediaCodec 的 encodeSurace (input surface).

// Add surface of GLSurafceView to preview target.
previewRequestBuilder.addTarget(previewSurface);
// Add surface of MediaCodec input surface to preview target.
previewRequestBuilder.addTarget(encodeSurface);

<<將編碼後影像寫入檔案>>

使用第一張編碼後影像的資訊 (bufferInfo) 配置並建立 (addTrack()) MediaMuxer 影像軌.

while (!eos) {
int outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, -1);
if (outputBufferIndex >= 0) {
// Encode pre-defined amount of frame
if(frameLimit > 0) {
ByteBuffer outputBuffer = encoder.getOutputBuffer(outputBufferIndex);
if (!muxerStarted) {
MediaFormat format = encoder.getOutputFormat(outputBufferIndex);
Log.v(TAG, "Adding video track " + format);
videoTrackIndex = mediaMuxer.addTrack(format);
Log.v(TAG, "MediaMuxer start");
mediaMuxer.start();
muxerStarted = true;
}

使用 MediaMuxer 將影像軌寫入檔案.

            mediaMuxer.writeSampleData(videoTrackIndex, outputBuffer, bufferInfo);
if (--frameLimit == 0) {
Log.v(TAG, "MediaMuxer stop");
mediaMuxer.stop();
muxerStarted = false;
}
}
encoder.releaseOutputBuffer(outputBufferIndex, false);

<<原始碼>>

GitHub SampleCamera2 

(commit de73c87c4bfe8a7376133f5231760048ba3b84d9)

(完)

 

文章標籤
創作者介紹
創作者 版大 的頭像
版大

嵌入式系統

版大 發表在 痞客邦 留言(0) 人氣()