Comment utiliser Android MediaCodec encoder les données de la Caméra(YUV420sp)
Je vous remercie pour votre attention!
Je veux utiliser Android MediaCodec Api pour coder l'image de la vidéo qui a acquis à partir de la Caméra,
malheureusement, je n'ai pas de succès pour les faire! J'ai pas encore familier avec le MediaCodec API。
Le suivi est mes codes,j'ai besoin de votre aide pour comprendre ce que je dois faire.
1、Le réglage de la Caméra:
Parameters parameters = mCamera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
parameters.setPreviewSize(320, 240);
mCamera.setParameters(parameters);
2、Ensemble de l'encodeur:
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);
}
Je suppose que le problème est survenu dans le codeur de la méthode,la méthode sera utilisée dans l'Aperçu de la Caméra de Rappel ,comme
initCodec();
//mCamera.setPreviewCallback(new MyPreviewCallback());
mCamera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
encode(data);
}
});
J'ai juste aucune idée de comment le faire correctement avec le MediaCodec API.Pouvez-vous me donner quelques conseils ou des liens à ce sujet?
Merci!
OriginalL'auteur Read Mark | 2013-06-21
Vous devez vous connecter pour publier un commentaire.
J'ai résolu le problème.Comme suit:
Et ensuite,vous trouverez votre vidéo codé de couleur n'est pas droit, pour plus d'informations,s'il vous plaît aller ici MediaCodec et Caméra: espaces de couleurs ne correspondent pas
Il semble que vous essayez d'utiliser MediaCodec sur Android avec l'API < 16
OriginalL'auteur Read Mark
La YUV420 formats de sortie par la caméra sont incompatibles avec les formats acceptés par le MediaCodec AVC encoder. Dans le meilleur des cas, il s'agit essentiellement d'NV12 vs NV21 (U et V les avions sont inversés), nécessitant un manuel de réorganisation. Dans le pire des cas, comme d'Android 4.2, l'encodeur format d'entrée peut être spécifique à l'appareil.
Vous êtes mieux d'utiliser MediaRecorder pour connecter l'appareil à l'encodeur.
Mise à jour:
Il est maintenant possible de passer de l'appareil photo Surface aperçu de
MediaCodec
, au lieu d'utiliser le YUV données dans leByteBuffer
. C'est plus rapide et plus portable. Voir la CameraToMpegTest échantillon ici.Salut, @fadden. À propos de la "il est préférable d'utiliser MediaRecorder pour connecter l'appareil à l'encodeur.", est-il un exemple de code pour cela ? Merci.
MediaRecorder, de Surface ne permettent pas de traiter des images avant l'enregistrement et pourquoi pensez-vous que c'est plus rapide? Je pense que l'auteur connaît MediaRecord mais comme vous le voyez, il a demandé à propos de l'appareil photo cadres
OriginalL'auteur fadden