本文整理汇总了Java中android.media.MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED属性的典型用法代码示例。如果您正苦于以下问题:Java MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED属性的具体用法?Java MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED怎么用?Java MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED使用的例子?那么, 这里精选的属性代码示例或许可以为您提供帮助。您也可以进一步了解该属性所在类android.media.MediaCodec
的用法示例。
在下文中一共展示了MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED属性的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Java代码示例。
示例1: drainDecoder
private int drainDecoder(long timeoutUs) {
if (mIsDecoderEOS) return DRAIN_STATE_NONE;
int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs);
switch (result) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
return DRAIN_STATE_NONE;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
mAudioChannel.setActualDecodedFormat(mDecoder.getOutputFormat());
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mIsDecoderEOS = true;
mAudioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0);
} else if (mBufferInfo.size > 0) {
mAudioChannel.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs);
}
return DRAIN_STATE_CONSUMED;
}
示例2: handleCodecOutput
private void handleCodecOutput(MediaCodec mediaCodec,
ByteBuffer[] codecOutputBuffers,
MediaCodec.BufferInfo bufferInfo,
OutputStream outputStream)
throws IOException
{
int codecOutputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
while (codecOutputBufferIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
if (codecOutputBufferIndex >= 0) {
ByteBuffer encoderOutputBuffer = codecOutputBuffers[codecOutputBufferIndex];
encoderOutputBuffer.position(bufferInfo.offset);
encoderOutputBuffer.limit(bufferInfo.offset + bufferInfo.size);
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != MediaCodec.BUFFER_FLAG_CODEC_CONFIG) {
byte[] header = createAdtsHeader(bufferInfo.size - bufferInfo.offset);
outputStream.write(header);
byte[] data = new byte[encoderOutputBuffer.remaining()];
encoderOutputBuffer.get(data);
outputStream.write(data);
}
encoderOutputBuffer.clear();
mediaCodec.releaseOutputBuffer(codecOutputBufferIndex, false);
} else if (codecOutputBufferIndex== MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
codecOutputBuffers = mediaCodec.getOutputBuffers();
}
codecOutputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
}
}
示例3: checkDecoderStatus
/**
* MediaCodec#dequeueOutputBuffer()の戻り値のチェック
*
* @param decoderStatus MediaCodec#dequeueOutputBuffer()の戻り値
* @return true: デコード処理が行われた
*/
private boolean checkDecoderStatus(int decoderStatus) {
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
// dequeueOutputBufferの呼び出しがタイムアウト
if (mInputDone) {
Log.d(TAG, "no output from mDecoder available BUT the input is done.");
}
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
Log.d(TAG, "mDecoder output buffers changed");
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
Log.d(TAG, "mDecoder output format changed");
} else if (decoderStatus < 0) {
Log.d(TAG, "unexpected result from encoder.dequeueOutputBuffer: "
+ decoderStatus);
} else {
return true;
}
return false;
}
示例4: recorderEncoderLoop
/**
* Reads bytes from the given recorder and encodes them with the given encoder.
* Uses the (deprecated) Synchronous Processing using Buffer Arrays.
* <p/>
* Encoders (or codecs that generate compressed data) will create and return the codec specific
* data before any valid output buffer in output buffers marked with the codec-config flag.
* Buffers containing codec-specific-data have no meaningful timestamps.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void recorderEncoderLoop(MediaCodec codec, SpeechRecord speechRecord) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
codec.start();
// Getting some buffers (e.g. 4 of each) to communicate with the codec
ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
Log.i("input buffers " + codecInputBuffers.length + "; output buffers: " + codecOutputBuffers.length);
boolean doneSubmittingInput = false;
int numRetriesDequeueOutputBuffer = 0;
int index;
while (true) {
if (!doneSubmittingInput) {
index = codec.dequeueInputBuffer(DEQUEUE_TIMEOUT);
if (index >= 0) {
int size = queueInputBuffer(codec, codecInputBuffers, index, speechRecord);
if (size == -1) {
codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
Log.i("enc: in: EOS");
doneSubmittingInput = true;
} else {
Log.i("enc: in: " + size);
mNumBytesSubmitted += size;
}
} else {
Log.i("enc: in: timeout, will try again");
}
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
index = codec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT);
Log.i("enc: out: flags/index: " + info.flags + "/" + index);
if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
Log.i("enc: out: INFO_TRY_AGAIN_LATER: " + numRetriesDequeueOutputBuffer);
if (++numRetriesDequeueOutputBuffer > MAX_NUM_RETRIES_DEQUEUE_OUTPUT_BUFFER) {
break;
}
} else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat format = codec.getOutputFormat();
Log.i("enc: out: INFO_OUTPUT_FORMAT_CHANGED: " + format.toString());
} else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
codecOutputBuffers = codec.getOutputBuffers();
Log.i("enc: out: INFO_OUTPUT_BUFFERS_CHANGED");
} else {
dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
mNumBytesDequeued += info.size;
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.i("enc: out: EOS");
break;
}
}
}
codec.stop();
codec.release();
}
}
开发者ID:vaibhavs4424,项目名称:AI-Powered-Intelligent-Banking-Platform,代码行数:63,代码来源:EncodedAudioRecorder.java
示例5: drainEncoder
private int drainEncoder(long timeoutUs) {
if (mIsEncoderEOS) return DRAIN_STATE_NONE;
int result = mEncoder.dequeueOutputBuffer(mBufferInfo, timeoutUs);
switch (result) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
return DRAIN_STATE_NONE;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
if (mActualOutputFormat != null) {
throw new RuntimeException("Audio output format changed twice.");
}
mActualOutputFormat = mEncoder.getOutputFormat();
mMuxer.setOutputFormat(SAMPLE_TYPE, mActualOutputFormat);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
mEncoderBuffers = new MediaCodecBufferCompatWrapper(mEncoder);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
if (mActualOutputFormat == null) {
throw new RuntimeException("Could not determine actual output format.");
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mIsEncoderEOS = true;
mBufferInfo.set(0, 0, 0, mBufferInfo.flags);
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// SPS or PPS, which should be passed by MediaFormat.
mEncoder.releaseOutputBuffer(result, false);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
mMuxer.writeSampleData(SAMPLE_TYPE, mEncoderBuffers.getOutputBuffer(result), mBufferInfo);
mWrittenPresentationTimeUs = mBufferInfo.presentationTimeUs;
mEncoder.releaseOutputBuffer(result, false);
return DRAIN_STATE_CONSUMED;
}
示例6: drainDecoder
private int drainDecoder(long timeoutUs) {
if (mIsDecoderEOS) return DRAIN_STATE_NONE;
int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs);
switch (result) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
return DRAIN_STATE_NONE;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mEncoder.signalEndOfInputStream();
mIsDecoderEOS = true;
mBufferInfo.size = 0;
}
boolean doRender = (mBufferInfo.size > 0);
// NOTE: doRender will block if buffer (of encoder) is full.
// Refer: http://bigflake.com/mediacodec/CameraToMpegTest.java.txt
mDecoder.releaseOutputBuffer(result, doRender);
if (doRender) {
mDecoderOutputSurfaceWrapper.awaitNewImage();
mDecoderOutputSurfaceWrapper.drawImage();
mEncoderInputSurfaceWrapper.setPresentationTime(mBufferInfo.presentationTimeUs * 1000);
mEncoderInputSurfaceWrapper.swapBuffers();
}
return DRAIN_STATE_CONSUMED;
}
示例7: handleOutput
protected void handleOutput() {
Log.d(TAG, TRACK_TYPE + " handle output ");
if ((mState == STATE_PLAYING || mState == STATE_SEEKING) && !mOutputDone) {
final int decoderStatus;
try {
decoderStatus = mMediaCodec.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
} catch (IllegalStateException e) {
Log.d(TAG, "can't dequeue output buffer: " + e.getMessage());
return;
}
Log.d(TAG, TRACK_TYPE + " decoder status: " + decoderStatus);
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
final MediaFormat newFormat = mMediaCodec.getOutputFormat();
if (DEBUG) Log.d(TAG, TRACK_TYPE + " decoder output format changed: " + newFormat);
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
if (DEBUG) Log.d(TAG, TRACK_TYPE + " decoder output buffer changed: ");
} else if (decoderStatus < 0) {
throw new RuntimeException(
"unexpected result from " + TRACK_TYPE + " decoder.dequeueOutputBuffer: " + decoderStatus);
} else {
Log.d(TAG, TRACK_TYPE + " Out put");
output(decoderStatus, mBufferInfo);
}
if ((mBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) && mState != STATE_SEEKING) {
Log.d(TAG, TRACK_TYPE + ":output EOS");
mBufferInfo = new MediaCodec.BufferInfo();
mOutputDone = true;
synchronized (mWeakPlayer.get().getSync()) {
mWeakPlayer.get().getSync().notify();
}
}
}
}
示例8: drainEncoder
private int drainEncoder(long timeoutUs) {
if (mIsEncoderEOS) return DRAIN_STATE_NONE;
int result = mEncoder.dequeueOutputBuffer(mBufferInfo, timeoutUs);
switch (result) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
return DRAIN_STATE_NONE;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
if (mActualOutputFormat != null) {
throw new RuntimeException("Audio output format changed twice.");
}
mActualOutputFormat = mEncoder.getOutputFormat();
mMuxer.setOutputFormat(QueuedMuxer.SampleType.AUDIO, mActualOutputFormat);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
if (mActualOutputFormat == null) {
throw new RuntimeException("Could not determine actual output format.");
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mIsEncoderEOS = true;
mBufferInfo.set(0, 0, 0, mBufferInfo.flags);
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// SPS or PPS, which should be passed by MediaFormat.
mEncoder.releaseOutputBuffer(result, false);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
mMuxer.writeSampleData(QueuedMuxer.SampleType.AUDIO, MediaUtil.getOutputBuffer(mEncoder, result), mBufferInfo);
mEncoder.releaseOutputBuffer(result, false);
return DRAIN_STATE_CONSUMED;
}
示例9: drainDecoder
private int drainDecoder(long timeoutUs) {
if (mIsDecoderEOS) return DRAIN_STATE_NONE;
int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs);
switch (result) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
return DRAIN_STATE_NONE;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mEncoder.signalEndOfInputStream();
mIsDecoderEOS = true;
mBufferInfo.size = 0;
}
boolean doRender = (mBufferInfo.size > 0);
// NOTE: doRender will block if buffer (of encoder) is full.
// Refer: http://bigflake.com/mediacodec/CameraToMpegTest.java.txt
mDecoder.releaseOutputBuffer(result, doRender);
if (doRender) {
mDecoderOutputSurfaceWrapper.awaitNewImage();
mDecoderOutputSurfaceWrapper.drawImage(mBufferInfo.presentationTimeUs * 1000);
mEncoderInputSurfaceWrapper.setPresentationTime(mBufferInfo.presentationTimeUs * 1000);
// swapBuffers后之前的OpenGL操作会渲染到InputSurface绑定的Surface中
mEncoderInputSurfaceWrapper.swapBuffers();
}
return DRAIN_STATE_CONSUMED;
}
示例10: drainEncoder
private int drainEncoder(long timeoutUs) {
if (mIsEncoderEOS) return DRAIN_STATE_NONE;
int result = mEncoder.dequeueOutputBuffer(mBufferInfo, timeoutUs);
switch (result) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
return DRAIN_STATE_NONE;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
if (mActualOutputFormat != null) {
throw new RuntimeException("Video output format changed twice.");
}
mActualOutputFormat = mEncoder.getOutputFormat();
mMuxer.setOutputFormat(QueuedMuxer.SampleType.VIDEO, mActualOutputFormat);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
mEncoderOutputBuffers = mEncoder.getOutputBuffers();
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
if (mActualOutputFormat == null) {
throw new RuntimeException("Could not determine actual output format.");
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mIsEncoderEOS = true;
mBufferInfo.set(0, 0, 0, mBufferInfo.flags);
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// SPS or PPS, which should be passed by MediaFormat.
mEncoder.releaseOutputBuffer(result, false);
return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
}
mMuxer.writeSampleData(QueuedMuxer.SampleType.VIDEO, mEncoderOutputBuffers[result], mBufferInfo);
mEncoder.releaseOutputBuffer(result, false);
return DRAIN_STATE_CONSUMED;
}
示例11: drainOutputBuffer
/**
* @return True if it may be possible to drain more output data. False otherwise.
* @throws ExoPlaybackException If an error occurs draining the output buffer.
*/
@SuppressWarnings("deprecation")
private boolean drainOutputBuffer(long positionUs, long elapsedRealtimeUs)
throws ExoPlaybackException {
if (outputStreamEnded) {
return false;
}
if (outputIndex < 0) {
outputIndex = codec.dequeueOutputBuffer(outputBufferInfo, getDequeueOutputBufferTimeoutUs());
}
if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
processOutputFormat();
return true;
} else if (outputIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
codecCounters.outputBuffersChangedCount++;
return true;
} else if (outputIndex < 0) {
if (codecNeedsEosPropagationWorkaround && (inputStreamEnded
|| codecReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM)) {
processEndOfStream();
return true;
}
return false;
}
if ((outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
processEndOfStream();
return false;
}
int decodeOnlyIndex = getDecodeOnlyIndex(outputBufferInfo.presentationTimeUs);
if (processOutputBuffer(positionUs, elapsedRealtimeUs, codec, outputBuffers[outputIndex],
outputBufferInfo, outputIndex, decodeOnlyIndex != -1)) {
onProcessedOutputBuffer(outputBufferInfo.presentationTimeUs);
if (decodeOnlyIndex != -1) {
decodeOnlyPresentationTimestamps.remove(decodeOnlyIndex);
}
outputIndex = -1;
return true;
}
return false;
}
示例12: drainEncoder
/**
* Extracts all pending data from the encoder.
* <p>
* If endOfStream is not set, this returns when there is no more data to drain. If it
* is set, we send EOS to the encoder, and then iterate until we see EOS on the output.
* Calling this with endOfStream set should be done once, right before stopping the muxer.
*/
@SuppressWarnings("deprecation")
private void drainEncoder(boolean eos) {
checkState();
//logv("Drain encoder: " + eos);
if (eos) {
//logv("Sending EOS to encoder");
mEncoder.signalEndOfInputStream();
}
int encoderStatus;
while ((encoderStatus = getEncoderStatus(eos)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
switch (encoderStatus) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
throw new RuntimeException("Output buffers changed twice");
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
if (mTrackId != -1) {
throw new RuntimeException("Format changed twice");
}
// Now that we have the Magic Goodies, start the muxer
final MediaFormat format = mEncoder.getOutputFormat();
//logv("Encoder output format changed: " + format);
mTrackId = mMuxer.addTrack(format);
mMuxer.start();
break;
default:
if (encoderStatus >= 0) {
final ByteBuffer encodedData = mOutputBuffers[encoderStatus];
if (encodedData == null) {
throw new RuntimeException (
"EncoderOutputBuffer " + encoderStatus + " was null"
);
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// The codec config data was pulled out and fed to the muxer when we got
// the INFO_OUTPUT_FORMAT_CHANGED status. Ignore it.
//logv("ignoring BUFFER_FLAG_CODEC_CONFIG");
mBufferInfo.size = 0;
}
if (mBufferInfo.size != 0) {
if (mTrackId == -1) {
throw new RuntimeException("Muxer hasn't started");
}
// Adjust the ByteBuffer values to match BufferInfo (not needed?)
encodedData.position(mBufferInfo.offset);
encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
mMuxer.writeSampleData(mTrackId, encodedData, mBufferInfo);
//logv("Sent " + mBufferInfo.size + " bytes to muxer");
}
mEncoder.releaseOutputBuffer(encoderStatus, false);
} else {
//noinspection StatementWithEmptyBody
if (encoderStatus != INFO_NO_OUTPUT_AVAILABLE_YET) {
logw("unexpected encoder status: " + encoderStatus);
}
}
break;
}
}
}
示例13: dequeueOutputBuffer
private DecodedOutputBuffer dequeueOutputBuffer(int dequeueTimeoutMs) {
checkOnMediaCodecThread();
if (decodeStartTimeMs.isEmpty()) {
return null;
}
// Drain the decoder until receiving a decoded buffer or hitting
// MediaCodec.INFO_TRY_AGAIN_LATER.
final MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
while (true) {
final int result =
mediaCodec.dequeueOutputBuffer(info, TimeUnit.MILLISECONDS.toMicros(dequeueTimeoutMs));
switch (result) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
outputBuffers = mediaCodec.getOutputBuffers();
Logging.d(TAG, "Decoder output buffers changed: " + outputBuffers.length);
if (hasDecodedFirstFrame) {
throw new RuntimeException("Unexpected output buffer change event.");
}
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
MediaFormat format = mediaCodec.getOutputFormat();
Logging.d(TAG, "Decoder format changed: " + format.toString());
int new_width = format.getInteger(MediaFormat.KEY_WIDTH);
int new_height = format.getInteger(MediaFormat.KEY_HEIGHT);
if (hasDecodedFirstFrame && (new_width != width || new_height != height)) {
throw new RuntimeException("Unexpected size change. Configured " + width + "*" + height
+ ". New " + new_width + "*" + new_height);
}
width = format.getInteger(MediaFormat.KEY_WIDTH);
height = format.getInteger(MediaFormat.KEY_HEIGHT);
if (!useSurface && format.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
colorFormat = format.getInteger(MediaFormat.KEY_COLOR_FORMAT);
Logging.d(TAG, "Color: 0x" + Integer.toHexString(colorFormat));
if (!supportedColorList.contains(colorFormat)) {
throw new IllegalStateException("Non supported color format: " + colorFormat);
}
}
if (format.containsKey("stride")) {
stride = format.getInteger("stride");
}
if (format.containsKey("slice-height")) {
sliceHeight = format.getInteger("slice-height");
}
Logging.d(TAG, "Frame stride and slice height: " + stride + " x " + sliceHeight);
stride = Math.max(width, stride);
sliceHeight = Math.max(height, sliceHeight);
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
return null;
default:
hasDecodedFirstFrame = true;
TimeStamps timeStamps = decodeStartTimeMs.remove();
long decodeTimeMs = SystemClock.elapsedRealtime() - timeStamps.decodeStartTimeMs;
if (decodeTimeMs > MAX_DECODE_TIME_MS) {
Logging.e(TAG, "Very high decode time: " + decodeTimeMs + "ms"
+ ". Q size: " + decodeStartTimeMs.size()
+ ". Might be caused by resuming H264 decoding after a pause.");
decodeTimeMs = MAX_DECODE_TIME_MS;
}
return new DecodedOutputBuffer(result, info.offset, info.size,
TimeUnit.MICROSECONDS.toMillis(info.presentationTimeUs), timeStamps.timeStampMs,
timeStamps.ntpTimeStampMs, decodeTimeMs, SystemClock.elapsedRealtime());
}
}
}
示例14: writeMuxerDataFromEncoding
/**
* 编码后的数据写入Muxer中
*/
private void writeMuxerDataFromEncoding(boolean isEOS) {
if (!isEncoding) {
return;
}
Log.d(TAG, "writeMuxerDataFromEncoding isEOS:" + isEOS);
ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers();
while (isEncoding) {
int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(mBufferInfo, 10);
Log.d(TAG, "outputBufferIndex=" + outputBufferIndex + " flags:" + mBufferInfo.flags);
if (outputBufferIndex >= 0) {
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
mBufferInfo.size = 0;
}
ByteBuffer encodedData = outputBuffers[outputBufferIndex];
if (mBufferInfo.size != 0) {
mMediaMuxer.writeSampleData(mTrackIndex, encodedData, mBufferInfo);
}
mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.e(TAG, "Encoding end of stream");
isEncoding = false;
break;
}
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = mMediaCodec.getOutputBuffers();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat mediaFormat = mMediaCodec.getOutputFormat();
mTrackIndex = mMediaMuxer.addAudioTrack(mediaFormat);
mMediaMuxer.start();
Log.d(TAG, "audio mediaMuxer start");
} else if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
if (!isEOS) {
break;
}
}
}
}
示例15: writeMuxerDataFromEncoding
/**
* 编码后的数据写入Muxer中
*/
private void writeMuxerDataFromEncoding(boolean isEOS) {
Log.d(TAG, "writeMuxerDataFromEncoding start isEOS:" + isEOS);
if (!isEncoding) {
Log.d(TAG, "writeMuxerDataFromEncoding end isEOS:" + isEOS + ",isEncoding:" + isEncoding);
return;
}
if (isRequestEOS != isEOS) {
//请求停止了,但是仍旧有离屏的画面更新回调,要求编码,丢弃
Log.d(TAG, "Already request eos,so ignore dequeuebuffer.");
Log.d(TAG, "writeMuxerDataFromEncoding end isEOS:" + isEOS + ",isRequestEOS:" + isRequestEOS);
isEncoding = true;
return;
}
if (isEOS && !hasFrameData) {
//请求停止,但是没有写入过一帧数据,不能从MediaCodec中拉取数据,直接返回
Log.d(TAG, "writeMuxerDataFromEncoding end without frame!");
mMediaMuxer.cancel();
isEncoding = true;
return;
}
if (isEOS) {
mMediaCodec.signalEndOfInputStream();
}
ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers();
while (isEncoding) {
int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(mBufferInfo, 10);
Log.d(TAG, "outputBufferIndex=" + outputBufferIndex + " flags:" + mBufferInfo.flags);
if (outputBufferIndex >= 0) {
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
mBufferInfo.size = 0;
}
ByteBuffer encodedData = outputBuffers[outputBufferIndex];
if (mBufferInfo.size != 0) {
mMediaMuxer.writeSampleData(mTrackIndex, encodedData, mBufferInfo);
hasFrameData = true;
}
mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.e(TAG, "Encoding end of stream");
isEncoding = false;
break; // out of while
}
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = mMediaCodec.getOutputBuffers();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat mediaFormat = mMediaCodec.getOutputFormat();
mTrackIndex = mMediaMuxer.addVideoTrack(mediaFormat);
mMediaMuxer.start();
} else if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
if (!isEOS) {
break;
}
}
}
Log.d(TAG, "writeMuxerDataFromEncoding end isEOS:" + isEOS);
}