下面列出了android.media.MediaCodec# createByCodecName ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@CalledByNative
private static MediaCodecBridge create(String mime, boolean isSecure) {
MediaCodec mediaCodec = null;
try {
// |isSecure| only applies to video decoders.
if (mime.startsWith("video") && isSecure) {
mediaCodec = MediaCodec.createByCodecName(getSecureDecoderNameForMime(mime));
} else {
mediaCodec = MediaCodec.createDecoderByType(mime);
}
} catch (Exception e) {
Log.e(TAG, "Failed to create MediaCodec: " + mime + ", isSecure: "
+ isSecure + ", " + e.toString());
}
if (mediaCodec == null) {
return null;
}
return new MediaCodecBridge(mediaCodec);
}
@CalledByNative
private static MediaCodecBridge create(String mime, boolean isSecure) {
MediaCodec mediaCodec = null;
try {
// |isSecure| only applies to video decoders.
if (mime.startsWith("video") && isSecure) {
mediaCodec = MediaCodec.createByCodecName(getSecureDecoderNameForMime(mime));
} else {
mediaCodec = MediaCodec.createDecoderByType(mime);
}
} catch (Exception e) {
Log.e(TAG, "Failed to create MediaCodec: " + mime + ", isSecure: "
+ isSecure + ", " + e.toString());
}
if (mediaCodec == null) {
return null;
}
return new MediaCodecBridge(mediaCodec);
}
private @NonNull
MediaCodec createVideoEncoder(
final @NonNull MediaCodecInfo codecInfo,
final @NonNull MediaFormat format,
final @NonNull AtomicReference<Surface> surfaceReference) throws IOException {
final MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
// Must be called before start()
surfaceReference.set(encoder.createInputSurface());
encoder.start();
return encoder;
}
static
MediaCodec createByCodecName(String codecName) {
try {
// In the L-SDK this call can throw IOException so in order to work in
// both cases catch an exception.
return MediaCodec.createByCodecName(codecName);
} catch (Exception e) {
return null;
}
}
/**
* Get a list of supported android codec mimes.
*/
@CalledByNative
private static CodecInfo[] getCodecsInfo() {
Map<String, CodecInfo> CodecInfoMap = new HashMap<String, CodecInfo>();
int count = MediaCodecList.getCodecCount();
for (int i = 0; i < count; ++i) {
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
if (info.isEncoder()) {
continue;
}
boolean secureDecoderSupported = false;
String codecString = info.getName();
// ".secure" codecs sometimes crash instead of throwing on pre-JBMR2
// platforms, but this code isn't run on them anyway (MediaDrm
// unavailable) so we side-step the issue. http://crbug.com/314868
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
String secureCodecName = codecString + ".secure";
try {
MediaCodec secureCodec = MediaCodec.createByCodecName(secureCodecName);
if (secureCodec != null) {
secureDecoderSupported = true;
secureCodec.release();
}
} catch (Exception e) {
Log.e(TAG, "Failed to create " + secureCodecName);
}
}
String[] supportedTypes = info.getSupportedTypes();
for (int j = 0; j < supportedTypes.length; ++j) {
if (!CodecInfoMap.containsKey(supportedTypes[j]) || secureDecoderSupported) {
CodecInfoMap.put(supportedTypes[j], new CodecInfo(
supportedTypes[j], codecString, secureDecoderSupported));
}
}
}
return CodecInfoMap.values().toArray(
new CodecInfo[CodecInfoMap.size()]);
}
/**
* Creates a decoder for the given format, which outputs to the given surface.
*
* @param inputFormat the format of the stream to decode
* @param surface into which to decode the frames
*/
private MediaCodec createVideoDecoder(
MediaCodecList mcl, MediaFormat inputFormat, Surface surface){
try {
MediaCodec decoder = MediaCodec.createByCodecName(mcl.findDecoderForFormat(inputFormat));
decoder.configure(inputFormat, surface, null, 0);
decoder.start();
return decoder;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Video encoding is done by a MediaCodec.
* But here we will use the buffer-to-surface methode
*/
@SuppressLint({ "InlinedApi", "NewApi" })
protected void encodeWithMediaCodecMethod2() throws RuntimeException, IOException {
Log.d(TAG,"Video encoded using the MediaCodec API with a surface");
// Updates the parameters of the camera if needed
createCamera();
updateCamera();
// Estimates the framerate of the camera
measureFramerate();
EncoderDebugger debugger = EncoderDebugger.debug(mSettings, mQuality.resX, mQuality.resY);
mMediaCodec = MediaCodec.createByCodecName(debugger.getEncoderName());
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", mQuality.resX, mQuality.resY);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, mQuality.bitrate);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mQuality.framerate);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
mMediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Surface surface = mMediaCodec.createInputSurface();
((SurfaceView)mSurfaceView).addMediaCodecSurface(surface);
mMediaCodec.start();
// The packetizer encapsulates the bit stream in an RTP stream and send it over the network
mPacketizer.setDestination(mDestination, mRtpPort, mRtcpPort);
mPacketizer.setInputStream(new MediaCodecInputStream(mMediaCodec));
mPacketizer.start();
mStreaming = true;
}
/**
* Creates an encoder for the given format using the specified codec.
*
* @param codecName of the codec to use
* @param format of the stream to be produced
*/
private MediaCodec createAudioEncoder(String codecName, MediaFormat format) {
try {
MediaCodec encoder = MediaCodec.createByCodecName(codecName);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
return encoder;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private void initCodec(MediaCodecInfo codecInfo, MediaCrypto crypto) throws Exception {
long codecInitializingTimestamp;
long codecInitializedTimestamp;
MediaCodec codec = null;
String name = codecInfo.name;
updateCodecOperatingRate();
boolean configureWithOperatingRate = codecOperatingRate > assumedMinimumCodecOperatingRate;
try {
codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createCodec:" + name);
codec = MediaCodec.createByCodecName(name);
TraceUtil.endSection();
TraceUtil.beginSection("configureCodec");
configureCodec(
codecInfo,
codec,
format,
crypto,
configureWithOperatingRate ? codecOperatingRate : CODEC_OPERATING_RATE_UNSET);
codecConfiguredWithOperatingRate = configureWithOperatingRate;
TraceUtil.endSection();
TraceUtil.beginSection("startCodec");
codec.start();
TraceUtil.endSection();
codecInitializedTimestamp = SystemClock.elapsedRealtime();
getCodecBuffers(codec);
} catch (Exception e) {
if (codec != null) {
resetCodecBuffers();
codec.release();
}
throw e;
}
this.codec = codec;
this.codecInfo = codecInfo;
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
onCodecInitialized(name, codecInitializedTimestamp, elapsed);
}
static MediaCodec createByCodecName(String codecName) {
try {
// In the L-SDK this call can throw IOException so in order to work in
// both cases catch an exception.
return MediaCodec.createByCodecName(codecName);
} catch (Exception e) {
return null;
}
}
private boolean initDecode(int width, int height) {
if (mediaCodecThread != null) {
throw new RuntimeException("Forgot to release()?");
}
DecoderProperties properties = findVp8HwDecoder();
if (properties == null) {
throw new RuntimeException("Cannot find HW VP8 decoder");
}
Log.d(TAG, "Java initDecode: " + width + " x " + height +
". Color: 0x" + Integer.toHexString(properties.colorFormat));
mediaCodecThread = Thread.currentThread();
try {
this.width = width;
this.height = height;
stride = width;
sliceHeight = height;
MediaFormat format =
MediaFormat.createVideoFormat(VP8_MIME_TYPE, width, height);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
Log.d(TAG, " Format: " + format);
mediaCodec = MediaCodec.createByCodecName(properties.codecName);
if (mediaCodec == null) {
return false;
}
mediaCodec.configure(format, null, null, 0);
mediaCodec.start();
colorFormat = properties.colorFormat;
outputBuffers = mediaCodec.getOutputBuffers();
inputBuffers = mediaCodec.getInputBuffers();
Log.d(TAG, "Input buffers: " + inputBuffers.length +
". Output buffers: " + outputBuffers.length);
return true;
} catch (IllegalStateException e) {
Log.e(TAG, "initDecode failed", e);
return false;
}
}
private void initCodec(MediaCodecInfo codecInfo, MediaCrypto crypto) throws Exception {
long codecInitializingTimestamp;
long codecInitializedTimestamp;
MediaCodec codec = null;
String codecName = codecInfo.name;
float codecOperatingRate =
Util.SDK_INT < 23
? CODEC_OPERATING_RATE_UNSET
: getCodecOperatingRateV23(rendererOperatingRate, inputFormat, getStreamFormats());
if (codecOperatingRate <= assumedMinimumCodecOperatingRate) {
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
}
try {
codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createCodec:" + codecName);
codec = MediaCodec.createByCodecName(codecName);
TraceUtil.endSection();
TraceUtil.beginSection("configureCodec");
configureCodec(codecInfo, codec, inputFormat, crypto, codecOperatingRate);
TraceUtil.endSection();
TraceUtil.beginSection("startCodec");
codec.start();
TraceUtil.endSection();
codecInitializedTimestamp = SystemClock.elapsedRealtime();
getCodecBuffers(codec);
} catch (Exception e) {
if (codec != null) {
resetCodecBuffers();
codec.release();
}
throw e;
}
this.codec = codec;
this.codecInfo = codecInfo;
this.codecOperatingRate = codecOperatingRate;
codecFormat = inputFormat;
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
codecNeedsReconfigureWorkaround = codecNeedsReconfigureWorkaround(codecName);
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, codecFormat);
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround =
codecNeedsMonoChannelCountWorkaround(codecName, codecFormat);
codecNeedsEosPropagation =
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
resetInputBuffer();
resetOutputBuffer();
codecHotswapDeadlineMs =
getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
: C.TIME_UNSET;
codecReconfigured = false;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
codecReceivedEos = false;
codecReceivedBuffers = false;
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
codecNeedsAdaptationWorkaroundBuffer = false;
shouldSkipAdaptationWorkaroundOutputBuffer = false;
isDecodeOnlyOutputBuffer = false;
isLastOutputBuffer = false;
waitingForFirstSyncSample = true;
decoderCounters.decoderInitCount++;
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
onCodecInitialized(codecName, codecInitializedTimestamp, elapsed);
}
/**
* Instantiates and starts the decoder.
*/
private void configureDecoder() {
byte[] prefix = new byte[] {0x00,0x00,0x00,0x01};
ByteBuffer csd0 = ByteBuffer.allocate(4+mSPS.length+4+mPPS.length);
csd0.put(new byte[] {0x00,0x00,0x00,0x01});
csd0.put(mSPS);
csd0.put(new byte[] {0x00,0x00,0x00,0x01});
csd0.put(mPPS);
mDecoder = MediaCodec.createByCodecName(mDecoderName);
MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
mediaFormat.setByteBuffer("csd-0", csd0);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mDecoderColorFormat);
mDecoder.configure(mediaFormat, null, null, 0);
mDecoder.start();
ByteBuffer[] decInputBuffers = mDecoder.getInputBuffers();
int decInputIndex = mDecoder.dequeueInputBuffer(1000000/FRAMERATE);
if (decInputIndex>=0) {
decInputBuffers[decInputIndex].clear();
decInputBuffers[decInputIndex].put(prefix);
decInputBuffers[decInputIndex].put(mSPS);
mDecoder.queueInputBuffer(decInputIndex, 0, decInputBuffers[decInputIndex].position(), timestamp(), 0);
} else {
if (VERBOSE) Log.e(TAG,"No buffer available !");
}
decInputIndex = mDecoder.dequeueInputBuffer(1000000/FRAMERATE);
if (decInputIndex>=0) {
decInputBuffers[decInputIndex].clear();
decInputBuffers[decInputIndex].put(prefix);
decInputBuffers[decInputIndex].put(mPPS);
mDecoder.queueInputBuffer(decInputIndex, 0, decInputBuffers[decInputIndex].position(), timestamp(), 0);
} else {
if (VERBOSE) Log.e(TAG,"No buffer available !");
}
}
private void initCodec(MediaCodecInfo codecInfo, MediaCrypto crypto) throws Exception {
long codecInitializingTimestamp;
long codecInitializedTimestamp;
MediaCodec codec = null;
String codecName = codecInfo.name;
float codecOperatingRate =
Util.SDK_INT < 23
? CODEC_OPERATING_RATE_UNSET
: getCodecOperatingRateV23(rendererOperatingRate, inputFormat, getStreamFormats());
if (codecOperatingRate <= assumedMinimumCodecOperatingRate) {
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
}
try {
codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createCodec:" + codecName);
codec = MediaCodec.createByCodecName(codecName);
TraceUtil.endSection();
TraceUtil.beginSection("configureCodec");
configureCodec(codecInfo, codec, inputFormat, crypto, codecOperatingRate);
TraceUtil.endSection();
TraceUtil.beginSection("startCodec");
codec.start();
TraceUtil.endSection();
codecInitializedTimestamp = SystemClock.elapsedRealtime();
getCodecBuffers(codec);
} catch (Exception e) {
if (codec != null) {
resetCodecBuffers();
codec.release();
}
throw e;
}
this.codec = codec;
this.codecInfo = codecInfo;
this.codecOperatingRate = codecOperatingRate;
codecFormat = inputFormat;
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
codecNeedsReconfigureWorkaround = codecNeedsReconfigureWorkaround(codecName);
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, codecFormat);
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround =
codecNeedsMonoChannelCountWorkaround(codecName, codecFormat);
codecNeedsEosPropagation =
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
resetInputBuffer();
resetOutputBuffer();
codecHotswapDeadlineMs =
getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
: C.TIME_UNSET;
codecReconfigured = false;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
codecReceivedEos = false;
codecReceivedBuffers = false;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
codecNeedsAdaptationWorkaroundBuffer = false;
shouldSkipAdaptationWorkaroundOutputBuffer = false;
isDecodeOnlyOutputBuffer = false;
isLastOutputBuffer = false;
waitingForFirstSyncSample = true;
decoderCounters.decoderInitCount++;
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
onCodecInitialized(codecName, codecInitializedTimestamp, elapsed);
}
private void initCodec(MediaCodecInfo codecInfo, MediaCrypto crypto) throws Exception {
long codecInitializingTimestamp;
long codecInitializedTimestamp;
MediaCodec codec = null;
String codecName = codecInfo.name;
float codecOperatingRate =
Util.SDK_INT < 23
? CODEC_OPERATING_RATE_UNSET
: getCodecOperatingRateV23(rendererOperatingRate, inputFormat, getStreamFormats());
if (codecOperatingRate <= assumedMinimumCodecOperatingRate) {
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
}
try {
codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createCodec:" + codecName);
codec = MediaCodec.createByCodecName(codecName);
TraceUtil.endSection();
TraceUtil.beginSection("configureCodec");
configureCodec(codecInfo, codec, inputFormat, crypto, codecOperatingRate);
TraceUtil.endSection();
TraceUtil.beginSection("startCodec");
codec.start();
TraceUtil.endSection();
codecInitializedTimestamp = SystemClock.elapsedRealtime();
getCodecBuffers(codec);
} catch (Exception e) {
if (codec != null) {
resetCodecBuffers();
codec.release();
}
throw e;
}
this.codec = codec;
this.codecInfo = codecInfo;
this.codecOperatingRate = codecOperatingRate;
codecFormat = inputFormat;
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
codecNeedsReconfigureWorkaround = codecNeedsReconfigureWorkaround(codecName);
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, codecFormat);
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround =
codecNeedsMonoChannelCountWorkaround(codecName, codecFormat);
codecNeedsEosPropagation =
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
resetInputBuffer();
resetOutputBuffer();
codecHotswapDeadlineMs =
getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
: C.TIME_UNSET;
codecReconfigured = false;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
codecReceivedEos = false;
codecReceivedBuffers = false;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
codecNeedsAdaptationWorkaroundBuffer = false;
shouldSkipAdaptationWorkaroundOutputBuffer = false;
isDecodeOnlyOutputBuffer = false;
isLastOutputBuffer = false;
waitingForFirstSyncSample = true;
decoderCounters.decoderInitCount++;
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
onCodecInitialized(codecName, codecInitializedTimestamp, elapsed);
}
/**
* Video encoding is done by a MediaCodec.
*/
@SuppressLint("NewApi")
protected void encodeWithMediaCodecMethod1() throws RuntimeException, IOException {
Log.d(TAG,"Video encoded using the MediaCodec API with a buffer");
// Updates the parameters of the camera if needed
createCamera();
updateCamera();
// Estimates the framerate of the camera
measureFramerate();
// Starts the preview if needed
if (!mPreviewStarted) {
try {
mCamera.startPreview();
mPreviewStarted = true;
} catch (RuntimeException e) {
destroyCamera();
throw e;
}
}
EncoderDebugger debugger = EncoderDebugger.debug(mSettings, mQuality.resX, mQuality.resY);
final NV21Convertor convertor = debugger.getNV21Convertor();
mMediaCodec = MediaCodec.createByCodecName(debugger.getEncoderName());
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", mQuality.resX, mQuality.resY);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, mQuality.bitrate);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mQuality.framerate);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,debugger.getEncoderColorFormat());
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
mMediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mMediaCodec.start();
Camera.PreviewCallback callback = new Camera.PreviewCallback() {
long now = System.nanoTime()/1000, oldnow = now, i=0;
ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
oldnow = now;
now = System.nanoTime()/1000;
if (i++>3) {
i = 0;
//Log.d(TAG,"Measured: "+1000000L/(now-oldnow)+" fps.");
}
try {
int bufferIndex = mMediaCodec.dequeueInputBuffer(500000);
if (bufferIndex>=0) {
inputBuffers[bufferIndex].clear();
convertor.convert(data, inputBuffers[bufferIndex]);
mMediaCodec.queueInputBuffer(bufferIndex, 0, inputBuffers[bufferIndex].position(), now, 0);
} else {
Log.e(TAG,"No buffer available !");
}
} finally {
mCamera.addCallbackBuffer(data);
}
}
};
for (int i=0;i<10;i++) mCamera.addCallbackBuffer(new byte[convertor.getBufferSize()]);
mCamera.setPreviewCallbackWithBuffer(callback);
// The packetizer encapsulates the bit stream in an RTP stream and send it over the network
mPacketizer.setDestination(mDestination, mRtpPort, mRtcpPort);
mPacketizer.setInputStream(new MediaCodecInputStream(mMediaCodec));
mPacketizer.start();
mStreaming = true;
}
/**
* Instantiates and starts the decoder.
* @throws IOException The decoder cannot be configured
*/
private void configureDecoder() throws IOException {
byte[] prefix = new byte[] {0x00,0x00,0x00,0x01};
ByteBuffer csd0 = ByteBuffer.allocate(4+mSPS.length+4+mPPS.length);
csd0.put(new byte[] {0x00,0x00,0x00,0x01});
csd0.put(mSPS);
csd0.put(new byte[] {0x00,0x00,0x00,0x01});
csd0.put(mPPS);
mDecoder = MediaCodec.createByCodecName(mDecoderName);
MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
mediaFormat.setByteBuffer("csd-0", csd0);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mDecoderColorFormat);
mDecoder.configure(mediaFormat, null, null, 0);
mDecoder.start();
ByteBuffer[] decInputBuffers = mDecoder.getInputBuffers();
int decInputIndex = mDecoder.dequeueInputBuffer(1000000/FRAMERATE);
if (decInputIndex>=0) {
decInputBuffers[decInputIndex].clear();
decInputBuffers[decInputIndex].put(prefix);
decInputBuffers[decInputIndex].put(mSPS);
mDecoder.queueInputBuffer(decInputIndex, 0, decInputBuffers[decInputIndex].position(), timestamp(), 0);
} else {
if (VERBOSE) Log.e(TAG,"No buffer available !");
}
decInputIndex = mDecoder.dequeueInputBuffer(1000000/FRAMERATE);
if (decInputIndex>=0) {
decInputBuffers[decInputIndex].clear();
decInputBuffers[decInputIndex].put(prefix);
decInputBuffers[decInputIndex].put(mPPS);
mDecoder.queueInputBuffer(decInputIndex, 0, decInputBuffers[decInputIndex].position(), timestamp(), 0);
} else {
if (VERBOSE) Log.e(TAG,"No buffer available !");
}
}
private void encodeDecodeVideoFromBuffer(boolean toSurface) throws Exception {
MediaCodec encoder = null;
MediaCodec decoder = null;
try {
MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
if (codecInfo == null) {
// Don't fail CTS if they don't have an AVC codec (not here, anyway).
Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
return;
}
if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
int colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
// We avoid the device-specific limitations on width and height by using values that
// are multiples of 16, which all tested devices seem to be able to handle.
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
// Set some properties. Failing to specify some of these can cause the MediaCodec
// configure() call to throw an unhelpful exception.
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
if (VERBOSE) Log.d(TAG, "format: " + format);
// Create a MediaCodec for the desired codec, then configure it as an encoder with
// our desired properties.
encoder = MediaCodec.createByCodecName(codecInfo.getName());
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
// Create a MediaCodec for the decoder, just based on the MIME type. The various
// format details will be passed through the csd-0 meta-data later on.
decoder = MediaCodec.createDecoderByType(MIME_TYPE);
doEncodeDecodeVideoFromBuffer(encoder, colorFormat, decoder, toSurface);
} finally {
if (VERBOSE) Log.d(TAG, "releasing codecs");
if (encoder != null) {
encoder.stop();
encoder.release();
}
if (decoder != null) {
decoder.stop();
decoder.release();
}
Log.i(TAG, "Largest color delta: " + mLargestColorDelta);
}
}
/**
* Tests encoding and subsequently decoding video from frames generated into a buffer.
* <p>
* We encode several frames of a video test pattern using MediaCodec, then decode the
* output with MediaCodec and do some simple checks.
* <p>
* See http://b.android.com/37769 for a discussion of input format pitfalls.
*/
private void encodeDecodeVideoFromBuffer(boolean toSurface) throws Exception {
MediaCodec encoder = null;
MediaCodec decoder = null;
mLargestColorDelta = -1;
try {
MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
if (codecInfo == null) {
// Don't fail CTS if they don't have an AVC codec (not here, anyway).
Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
return;
}
if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
int colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
// We avoid the device-specific limitations on width and height by using values that
// are multiples of 16, which all tested devices seem to be able to handle.
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
// Set some properties. Failing to specify some of these can cause the MediaCodec
// configure() call to throw an unhelpful exception.
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
if (VERBOSE) Log.d(TAG, "format: " + format);
// Create a MediaCodec for the desired codec, then configure it as an encoder with
// our desired properties.
encoder = MediaCodec.createByCodecName(codecInfo.getName());
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
// Create a MediaCodec for the decoder, just based on the MIME type. The various
// format details will be passed through the csd-0 meta-data later on.
decoder = MediaCodec.createDecoderByType(MIME_TYPE);
doEncodeDecodeVideoFromBuffer(encoder, colorFormat, decoder, toSurface);
} finally {
if (VERBOSE) Log.d(TAG, "releasing codecs");
if (encoder != null) {
encoder.stop();
encoder.release();
}
if (decoder != null) {
decoder.stop();
decoder.release();
}
Log.i(TAG, "Largest color delta: " + mLargestColorDelta);
}
}
/**
* Tests encoding and subsequently decoding video from frames generated into a buffer.
* <p>
* We encode several frames of a video test pattern using MediaCodec, then decode the
* output with MediaCodec and do some simple checks.
*/
private void encodeDecodeVideoFromSurfaceToSurface() throws Exception {
MediaCodec encoder = null;
MediaCodec decoder = null;
InputSurface inputSurface = null;
OutputSurface outputSurface = null;
mLargestColorDelta = -1;
try {
MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
if (codecInfo == null) {
// Don't fail CTS if they don't have an AVC codec (not here, anyway).
Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
return;
}
if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
// We avoid the device-specific limitations on width and height by using values that
// are multiples of 16, which all tested devices seem to be able to handle.
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
// Set some properties. Failing to specify some of these can cause the MediaCodec
// configure() call to throw an unhelpful exception.
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
if (VERBOSE) Log.d(TAG, "format: " + format);
// Create the output surface.
outputSurface = new OutputSurface(mWidth, mHeight);
// Create a MediaCodec for the decoder, just based on the MIME type. The various
// format details will be passed through the csd-0 meta-data later on.
decoder = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat decoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
decoder.configure(format, outputSurface.getSurface(), null, 0);
decoder.start();
// Create a MediaCodec for the desired codec, then configure it as an encoder with
// our desired properties. Request a Surface to use for input.
encoder = MediaCodec.createByCodecName(codecInfo.getName());
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
inputSurface = new InputSurface(encoder.createInputSurface());
encoder.start();
doEncodeDecodeVideoFromSurfaceToSurface(encoder, inputSurface, colorFormat, decoder, outputSurface);
} finally {
if (VERBOSE) Log.d(TAG, "releasing codecs");
if (inputSurface != null) {
inputSurface.release();
}
if (outputSurface != null) {
outputSurface.release();
}
if (encoder != null) {
encoder.stop();
encoder.release();
}
if (decoder != null) {
decoder.stop();
decoder.release();
}
Log.i(TAG, "Largest color delta: " + mLargestColorDelta);
}
}