类android.media.MediaCodec源码实例Demo

下面列出了怎么用android.media.MediaCodec的API类实例代码及写法,或者点击链接到github查看源代码。


/**
 * @param trackType The track type that the renderer handles. One of the {@code C.TRACK_TYPE_*}
 *     constants defined in {@link C}.
 * @param mediaCodecSelector A decoder selector.
 * @param drmSessionManager For use with encrypted media. May be null if support for encrypted
 *     media is not required.
 * @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
 *     For example a media file may start with a short clear region so as to allow playback to
 *     begin in parallel with key acquisition. This parameter specifies whether the renderer is
 *     permitted to play clear regions of encrypted media files before {@code drmSessionManager}
 *     has obtained the keys necessary to decrypt encrypted regions of the media.
 * @param assumedMinimumCodecOperatingRate A codec operating rate that all codecs instantiated by
 *     this renderer are assumed to meet implicitly (i.e. without the operating rate being set
 *     explicitly using {@link MediaFormat#KEY_OPERATING_RATE}).
 */
public MediaCodecRenderer(
    int trackType,
    MediaCodecSelector mediaCodecSelector,
    @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
    boolean playClearSamplesWithoutKeys,
    float assumedMinimumCodecOperatingRate) {
  super(trackType);
  Assertions.checkState(Util.SDK_INT >= 16);
  this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector);
  this.drmSessionManager = drmSessionManager;
  this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
  this.assumedMinimumCodecOperatingRate = assumedMinimumCodecOperatingRate;
  buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
  flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance();
  formatHolder = new FormatHolder();
  decodeOnlyPresentationTimestamps = new ArrayList<>();
  outputBufferInfo = new MediaCodec.BufferInfo();
  codecReconfigurationState = RECONFIGURATION_STATE_NONE;
  codecReinitializationState = REINITIALIZATION_STATE_NONE;
  codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
  rendererOperatingRate = 1f;
}
 
源代码2 项目: LiTr   文件: AudioTrackTranscoderShould.java

@Test
public void addTrackWhenEncoderMediaFormatReceived() throws Exception {
    audioTrackTranscoder.lastExtractFrameResult = TrackTranscoder.RESULT_EOS_REACHED;
    audioTrackTranscoder.lastDecodeFrameResult = TrackTranscoder.RESULT_EOS_REACHED;
    audioTrackTranscoder.lastEncodeFrameResult = TrackTranscoder.RESULT_FRAME_PROCESSED;

    MediaFormat encoderMediaFormat = new MediaFormat();
    doReturn(MediaCodec.INFO_OUTPUT_FORMAT_CHANGED).when(encoder).dequeueOutputFrame(anyLong());
    doReturn(encoderMediaFormat).when(encoder).getOutputFormat();
    doReturn(AUDIO_TRACK).when(mediaTarget).addTrack(any(MediaFormat.class), anyInt());

    int result = audioTrackTranscoder.processNextFrame();

    ArgumentCaptor<MediaFormat> mediaFormatArgumentCaptor = ArgumentCaptor.forClass(MediaFormat.class);
    verify(mediaTarget).addTrack(mediaFormatArgumentCaptor.capture(), eq(AUDIO_TRACK));
    assertThat(mediaFormatArgumentCaptor.getValue(), is(encoderMediaFormat));

    assertThat(audioTrackTranscoder.targetTrack, is(AUDIO_TRACK));
    assertThat(result, is(TrackTranscoder.RESULT_OUTPUT_MEDIA_FORMAT_CHANGED));
}
 

@Override
protected MediaCodec internal_configure(MediaCodec previous_codec,
	final MediaFormat format) throws IOException {

	if (DEBUG) Log.v(TAG, "internal_configure:");
	format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);	// API >= 18
	format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate > 0 ? mBitRate : calcBitRate());
	format.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
	format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, mIFrameIntervals);
	if (DEBUG) Log.i(TAG, "format: " + format);

	if (previous_codec == null)
		previous_codec = MediaCodec.createEncoderByType(MIME_TYPE);
	previous_codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
	mSurface = previous_codec.createInputSurface();	// API >= 18
	return previous_codec;
}
 
源代码4 项目: AAVT   文件: SurfaceEncoder.java

private void openVideoEncoder(){
    AvLog.d(TAG,"openVideoEncoder startTime-->");
    if(mVideoEncoder==null){
        try {
            MediaFormat format=convertVideoConfigToFormat(mConfig.mVideo);
            mVideoEncoder= MediaCodec.createEncoderByType(mConfig.mVideo.mime);
            mVideoEncoder.configure(format,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);
            super.setSurface(mVideoEncoder.createInputSurface());
            super.setOutputSize(mConfig.mVideo.width,mConfig.mVideo.height);
            mVideoEncoder.start();
            isEncodeStarted=true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    AvLog.d(TAG,"openVideoEncoder endTime-->");
}
 
源代码5 项目: EZFilter   文件: AudioTrackTranscoder.java

@Override
public void setup() throws IOException {
    mExtractor.selectTrack(mTrackIndex);
    mEncoder = MediaCodec.createEncoderByType(mOutputFormat.getString(MediaFormat.KEY_MIME));
    mEncoder.configure(mOutputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mEncoder.start();
    mEncoderStarted = true;

    final MediaFormat inputFormat = mExtractor.getTrackFormat(mTrackIndex);
    mDecoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
    mDecoder.configure(inputFormat, null, null, 0);
    mDecoder.start();
    mDecoderStarted = true;

    mAudioChannel = new AudioChannel(mDecoder, mEncoder, mOutputFormat);
}
 

public MediaCodecDecoder(MediaExtractor extractor, boolean passive, int trackIndex,
                         OnDecoderEventListener listener)
        throws IllegalStateException, IOException
{
    // Apply the name of the concrete class that extends this base class to the logging tag
    // THis is really not a nice solution but there's no better one: http://stackoverflow.com/a/936724
    TAG = getClass().getSimpleName();

    if(extractor == null || trackIndex == INDEX_NONE) {
        throw new IllegalArgumentException("no track specified");
    }

    mExtractor = extractor;
    mPassive = passive;
    mTrackIndex = trackIndex;
    mFormat = extractor.getTrackFormat(mTrackIndex);

    mOnDecoderEventListener = listener;

    mCodec = MediaCodec.createDecoderByType(mFormat.getString(MediaFormat.KEY_MIME));

    mDecodingPTS = PTS_NONE;
}
 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
protected void recorderLoop(SpeechRecord speechRecord) {
    mNumBytesSubmitted = 0;
    mNumBytesDequeued = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        MediaFormat format = MediaFormatFactory.createMediaFormat(MediaFormatFactory.Type.FLAC, getSampleRate());
        List<String> componentNames = AudioUtils.getEncoderNamesForType(format.getString(MediaFormat.KEY_MIME));
        for (String componentName : componentNames) {
            Log.i("component/format: " + componentName + "/" + format);
            MediaCodec codec = AudioUtils.createCodec(componentName, format);
            if (codec != null) {
                recorderEncoderLoop(codec, speechRecord);
                if (Log.DEBUG) {
                    AudioUtils.showMetrics(format, mNumBytesSubmitted, mNumBytesDequeued);
                }
                break; // TODO: we use the first one that is suitable
            }
        }
    }
}
 

@Override
public void buildRenderers(DemoPlayer player) {
  Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
  Handler mainHandler = player.getMainHandler();

  // Build the video and audio renderers.
  DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, null);
  DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
  ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
      BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, mainHandler, player, 0);
  MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
      sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
      mainHandler, player, 50);
  MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
      MediaCodecSelector.DEFAULT, null, true, mainHandler, player,
      AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
  TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
      mainHandler.getLooper());

  // Invoke the callback.
  TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
  renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
  renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
  renderers[DemoPlayer.TYPE_TEXT] = textRenderer;
  player.onRenderers(renderers, bandwidthMeter);
}
 

/**
 * 硬解码获取实时帧数据并写入mp4文件
 *
 * @param index
 */
private void encodeToVideoTrack(int index) {
    // 获取到的实时帧视频数据
    ByteBuffer encodedData = mEncoder.getOutputBuffer(index);

    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.
        Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
        mBufferInfo.size = 0;
    }
    if (mBufferInfo.size == 0) {
        Log.d(TAG, "info.size == 0, drop it.");
        encodedData = null;
    } else {
        Log.d(TAG, "got buffer, info: size=" + mBufferInfo.size + ", presentationTimeUs="
                + mBufferInfo.presentationTimeUs + ", offset=" + mBufferInfo.offset);
    }
    if (encodedData != null) {
        mMuxer.writeSampleData(mVideoTrackIndex, encodedData, mBufferInfo);
    }
}
 
源代码10 项目: AndroidScreenShare   文件: AACEncoder.java

private void init() {
    mBufferInfo = new MediaCodec.BufferInfo();
    try {
        mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
        MediaFormat mediaFormat = MediaFormat.createAudioFormat(MIME_TYPE,
                sampleRate, channelCount);
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
        mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,
                KEY_AAC_PROFILE);
        mEncoder.configure(mediaFormat, null, null,
                MediaCodec.CONFIGURE_FLAG_ENCODE);
        mEncoder.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
 

public void write() {
    MediaCodecInputStream mediaCodecInputStream = aacEncoder.getMediaCodecInputStream();
    MediaCodecInputStream.readAll(mediaCodecInputStream, writeBuffer, new MediaCodecInputStream.OnReadAllCallback() {
        boolean shouldAddPacketHeader = true;
        byte[] header = new byte[7];
        @Override
        public void onReadOnce(byte[] buffer, int readSize, MediaCodec.BufferInfo bufferInfo) {
            if (readSize <= 0) {
                return;
            }
            try {
                Loggers.d("TestAudioEncoder", String.format("onReadOnce: readSize:%d, bufferInfo:%d", readSize, bufferInfo.size));
                if (shouldAddPacketHeader) {
                    Loggers.d("TestAudioEncoder", String.format("onReadOnce: add packet header"));
                    AACEncoder.addADTStoPacket(header, 7 + bufferInfo.size);
                    os.write(header);
                }
                os.write(buffer, 0, readSize);
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            shouldAddPacketHeader = readSize >= bufferInfo.size;
        }
    });
}
 

public UdpReceiverDecoderThread(Surface surface1, int port, Context context) {
    surface=surface1;
    mContext = context;
    this.port = port;
    nalu_data = new byte[NALU_MAXLEN];
    nalu_data_position = 0;
    settings= PreferenceManager.getDefaultSharedPreferences(mContext);
    DecoderMultiThread=settings.getBoolean("decoderMultiThread", true);
    userDebug=settings.getBoolean("userDebug", false);
    groundRecord=settings.getBoolean("groundRecording", false);
    if(userDebug){
        SharedPreferences.Editor editor=settings.edit();
        if(settings.getString("debugFile","").length()>=5000){
            editor.putString("debugFile","new Session !\n");
        }else{
            editor.putString("debugFile",settings.getString("debugFile","")+"\n\nnew Session !\n");
        }
        editor.commit();
    }
    info = new MediaCodec.BufferInfo();
}
 

@Override
public void init(int sampleRateHz, CodecAndBitrate codecAndBitrate, boolean allowVbr)
    throws EncoderException, IOException {
  codecType = lookupCodecType(codecAndBitrate);
  if (codecType == CodecType.UNSPECIFIED || codecType == CodecType.OGG_OPUS) {
    throw new EncoderException("Codec not set properly.");
  }
  if (codecType == CodecType.AMRWB && sampleRateHz != 16000) {
    throw new EncoderException("AMR-WB encoder requires a sample rate of 16kHz.");
  }
  MediaCodecInfo codecInfo = searchAmongAndroidSupportedCodecs(getMime(codecType));
  if (codecInfo == null) {
    throw new EncoderException("Encoder not found.");
  }
  this.codec = MediaCodec.createByCodecName(codecInfo.getName());

  MediaFormat format = getMediaFormat(codecAndBitrate, sampleRateHz);
  codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
  codec.start();
  initBuffers();

  addedHeader = false;
  successfullyFlushed = false;
  formatChangeReportedOnce = false;
}
 
源代码14 项目: ScreenCapture   文件: ScreenRecordThread.java

private void recordVirtualDisplay() {
    while (!mQuit.get()) {
        int index = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_US);
        Log.i(TAG, "dequeue output buffer index=" + index);
        if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            // 后续输出格式变化
            resetOutputFormat();
        } else if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
            // 请求超时
            Log.d(TAG, "retrieving buffers time out!");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
        } else if (index >= 0) {
            // 有效输出
            if (!mMuxerStarted) {
                Log.d(TAG, "mMuxerStarted not started");
                throw new IllegalStateException("MediaMuxer dose not call addTrack(format) ");
            }
            encodeToVideoTrack(index);

            mEncoder.releaseOutputBuffer(index, false);
        }
    }
}
 
源代码15 项目: PLDroidShortVideo   文件: MediaEncoder.java

public MediaEncoder(final MediaMuxerWrapper muxer, final MediaEncoderListener listener) {
    if (listener == null) throw new NullPointerException("MediaDecoderListener is null");
    if (muxer == null) throw new NullPointerException("MediaExtractorWrapper is null");
    mWeakMuxer = new WeakReference<MediaMuxerWrapper>(muxer);
    muxer.addEncoder(this);
    mListener = listener;
    synchronized (mLock) {
        // create BufferInfo here for effectiveness(to reduce GC)
        mBufferInfo = new MediaCodec.BufferInfo();
        // wait for starting thread
        new Thread(this, getClass().getSimpleName()).start();
        try {
            mLock.wait();
        } catch (final InterruptedException e) {
        }
    }
}
 
源代码16 项目: Telegram   文件: MediaCodecVideoRenderer.java

@Override
protected void configureCodec(
    MediaCodecInfo codecInfo,
    MediaCodec codec,
    Format format,
    MediaCrypto crypto,
    float codecOperatingRate) {
  String codecMimeType = codecInfo.codecMimeType;
  codecMaxValues = getCodecMaxValues(codecInfo, format, getStreamFormats());
  MediaFormat mediaFormat =
      getMediaFormat(
          format,
          codecMimeType,
          codecMaxValues,
          codecOperatingRate,
          deviceNeedsNoPostProcessWorkaround,
          tunnelingAudioSessionId);
  if (surface == null) {
    Assertions.checkState(shouldUseDummySurface(codecInfo));
    if (dummySurface == null) {
      dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
    }
    surface = dummySurface;
  }
  codec.configure(mediaFormat, surface, crypto, 0);
  if (Util.SDK_INT >= 23 && tunneling) {
    tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
  }
}
 
源代码17 项目: kickflip-android-sdk   文件: FFmpegMuxer.java

private void writePacketToFile(ByteBuffer buffer, MediaCodec.BufferInfo bufferInfo) {
    byte[] samples = new byte[bufferInfo.size];
    buffer.get(samples, bufferInfo.offset, bufferInfo.size);
    buffer.position(bufferInfo.offset);
    try {
        Files.write(samples, new File("/sdcard/Kickflip/packet_" + mPacketCount));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
 
源代码18 项目: kickflip-android-sdk   文件: FFmpegMuxer.java

@Override
public void writeSampleData(MediaCodec encoder, int trackIndex, int bufferIndex, ByteBuffer encodedData, MediaCodec.BufferInfo bufferInfo) {
    synchronized (mReadyFence) {
        if (mReady) {
            ByteBuffer muxerInput;
            if (formatRequiresBuffering()) {
                // Copy encodedData into another ByteBuffer, recycling if possible
                synchronized (mMuxerInputQueue) {
                    muxerInput = mMuxerInputQueue.get(trackIndex).isEmpty() ?
                            ByteBuffer.allocateDirect(encodedData.capacity()) : mMuxerInputQueue.get(trackIndex).remove();
                }
                muxerInput.put(encodedData);
                muxerInput.position(0);
                encoder.releaseOutputBuffer(bufferIndex, false);
                mHandler.sendMessage(mHandler.obtainMessage(MSG_WRITE_FRAME,
                        new WritePacketData(encoder, trackIndex, bufferIndex, muxerInput, bufferInfo)));
            } else {
                handleWriteSampleData(encoder, trackIndex, bufferIndex, encodedData, bufferInfo);
            }

        } else {
            Log.w(TAG, "Dropping frame because Muxer not ready!");
            releaseOutputBufer(encoder, encodedData, bufferIndex, trackIndex);
            if (formatRequiresBuffering())
                encoder.releaseOutputBuffer(bufferIndex, false);
        }
    }
}
 
源代码19 项目: patrol-android   文件: MediaCodecWrapper.java

/**
 * Write a media sample to the decoder.
 *
 * A "sample" here refers to a single atomic access unit in the media stream. The definition
 * of "access unit" is dependent on the type of encoding used, but it typically refers to
 * a single frame of video or a few seconds of audio. {@link MediaExtractor}
 * extracts data from a stream one sample at a time.
 *
 * @param extractor  Instance of {@link MediaExtractor} wrapping the media.
 *
 * @param presentationTimeUs The time, relative to the beginning of the media stream,
 * at which this buffer should be rendered.
 *
 * @param flags  Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
 * int, int, long, int)}
 *
 * @throws MediaCodec.CryptoException
 */
public boolean writeSample(final MediaExtractor extractor,
        final boolean isSecure,
        final long presentationTimeUs,
        int flags) {
    boolean result = false;
    boolean isEos = false;

    if (!mAvailableInputBuffers.isEmpty()) {
        int index = mAvailableInputBuffers.remove();
        ByteBuffer buffer = mInputBuffers[index];

        // reads the sample from the file using extractor into the buffer
        int size = extractor.readSampleData(buffer, 0);
        if (size <= 0) {
            flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
        }

        // Submit the buffer to the codec for decoding. The presentationTimeUs
        // indicates the position (play time) for the current sample.
        if (!isSecure) {
            mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
        } else {
            extractor.getSampleCryptoInfo(cryptoInfo);
            mDecoder.queueSecureInputBuffer(index, 0, cryptoInfo, presentationTimeUs, flags);
        }

        result = true;
    }
    return result;
}
 
源代码20 项目: K-Sonic   文件: MediaCodecVideoRenderer.java

private void clearRenderedFirstFrame() {
  renderedFirstFrame = false;
  // The first frame notification is triggered by renderOutputBuffer or renderOutputBufferV21 for
  // non-tunneled playback, onQueueInputBuffer for tunneled playback prior to API level 23, and
  // OnFrameRenderedListenerV23.onFrameRenderedListener for tunneled playback on API level 23 and
  // above.
  if (Util.SDK_INT >= 23 && tunneling) {
    MediaCodec codec = getCodec();
    // If codec is null then the listener will be instantiated in configureCodec.
    if (codec != null) {
      tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
    }
  }
}
 

@Override
protected @KeepCodecResult int canKeepCodec(
    MediaCodec codec, MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) {
  if (areAdaptationCompatible(codecInfo.adaptive, oldFormat, newFormat)
      && newFormat.width <= codecMaxValues.width
      && newFormat.height <= codecMaxValues.height
      && getMaxInputSize(codecInfo, newFormat) <= codecMaxValues.inputSize) {
    return oldFormat.initializationDataEquals(newFormat)
        ? KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION
        : KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION;
  }
  return KEEP_CODEC_RESULT_NO;
}
 

/**
 * Handle providing raw audio to MediaCodec InputBuffer
 * @param codec
 * @param inputBufferId
 * @return number bytes provided
 * @throws IOException
 */
private int queueCodecInputBuffer(MediaCodec codec, int inputBufferId) throws IOException {
    ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
    inputBuffer.clear();

    int bytesAvailable = inputAudioStream.available();
    int bytesToWrite = bytesAvailable < inputBuffer.limit() ? bytesAvailable : inputBuffer.limit();

    inputBuffer.put(IOUtils.toByteArray(inputAudioStream, bytesToWrite));
    codec.queueInputBuffer(inputBufferId, 0, bytesToWrite, 0, 0);
    return bytesToWrite;
}
 

/**
     * Method to set byte array to the MediaCodec encoder
     * @param buffer
     * @param length length of byte array, zero means EOS.
     * @param presentationTimeUs
     */
    protected void encode(final ByteBuffer buffer, final int length, final long presentationTimeUs) {
    	if (!mIsCapturing) return;
        final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
        while (mIsCapturing) {
	        final int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_USEC);
	        if (inputBufferIndex >= 0) {
	            final ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
	            inputBuffer.clear();
	            if (buffer != null) {
	            	inputBuffer.put(buffer);
	            }
//	            if (DEBUG) Log.v(TAG, "encode:queueInputBuffer");
	            if (length <= 0) {
	            	// send EOS
	            	mIsEOS = true;
	            	if (DEBUG) Log.i(TAG, "send BUFFER_FLAG_END_OF_STREAM");
	            	mMediaCodec.queueInputBuffer(inputBufferIndex, 0, 0,
	            		presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
		            break;
	            } else {
	            	mMediaCodec.queueInputBuffer(inputBufferIndex, 0, length,
	            		presentationTimeUs, 0);
	            }
	            break;
	        } else if (inputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
	        	// wait for MediaCodec encoder is ready to encode
	        	// nothing to do here because MediaCodec#dequeueInputBuffer(TIMEOUT_USEC)
	        	// will wait for maximum TIMEOUT_USEC(10msec) on each call
	        }
        }
    }
 

@TargetApi(21)
private void renderOutputBufferTimedV21(MediaCodec codec, int bufferIndex, long releaseTimeNs) {
  maybeNotifyVideoSizeChanged();
  TraceUtil.beginSection("releaseOutputBufferTimed");
  codec.releaseOutputBuffer(bufferIndex,false);// releaseTimeNs);
  TraceUtil.endSection();
  codecCounters.renderedOutputBufferCount++;
  maybeNotifyDrawnToSurface();
}
 

@Override
protected @KeepCodecResult int canKeepCodec(
    MediaCodec codec, MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) {
  if (codecInfo.isSeamlessAdaptationSupported(
          oldFormat, newFormat, /* isNewFormatComplete= */ true)
      && newFormat.width <= codecMaxValues.width
      && newFormat.height <= codecMaxValues.height
      && getMaxInputSize(codecInfo, newFormat) <= codecMaxValues.inputSize) {
    return oldFormat.initializationDataEquals(newFormat)
        ? KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION
        : KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION;
  }
  return KEEP_CODEC_RESULT_NO;
}
 

private void createMediaCodec() throws IOException {
    if (mMediaCodec != null) {
        if (DEBUG) {
            Log.w(TAG, "MediaCodec is already running.");
        }
        return;
    }

    if (mWorkThread != null) {
        if (DEBUG) {
            Log.w(TAG, "WorkThread is already running.");
        }
        return;
    }

    MediaFormat format = MediaFormat.createAudioFormat("audio/mp4a-latm",
            getSamplingRate(), getChannelCount());

    format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);

    mMediaCodec = MediaCodec.createDecoderByType("audio/mp4a-latm");
    mMediaCodec.configure(format, null, null, 0);
    mMediaCodec.start();

    mWorkThread = new WorkThread();
    mWorkThread.setName("AACLATM-DECODE");
    mWorkThread.start();
}
 

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void forceSyncFrame() {
  if (isRunning()) {
    Bundle bundle = new Bundle();
    bundle.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
    try {
      codec.setParameters(bundle);
    } catch (IllegalStateException e) {
      Log.e(TAG, "encoder need be running", e);
    }
  }
}
 

/**
 * Renders the output buffer with the specified index. This method is only called if the platform
 * API version of the device is less than 21.
 *
 * @param codec The codec that owns the output buffer.
 * @param index The index of the output buffer to drop.
 * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
 */
protected void renderOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) {
  maybeNotifyVideoSizeChanged();
  TraceUtil.beginSection("releaseOutputBuffer");
  codec.releaseOutputBuffer(index, true);
  TraceUtil.endSection();
  lastRenderTimeUs = SystemClock.elapsedRealtime() * 1000;
  decoderCounters.renderedOutputBufferCount++;
  consecutiveDroppedFrameCount = 0;
  maybeNotifyRenderedFirstFrame();
}
 
源代码29 项目: Lassi-Android   文件: MediaEncoder.java

/**
 * This encoder was attached to the engine. Keep the controller
 * and run the internal thread.
 */
final void prepare(@NonNull final MediaEncoderEngine.Controller controller, final long maxLengthMillis) {
    mController = controller;
    mBufferInfo = new MediaCodec.BufferInfo();
    mMaxLengthMillis = maxLengthMillis;
    mWorker = WorkerHandler.get(getName());
    LOG.i(getName(), "Prepare was called. Posting.");
    mWorker.post(new Runnable() {
        @Override
        public void run() {
            LOG.i(getName(), "Prepare was called. Executing.");
            onPrepare(controller, maxLengthMillis);
        }
    });
}
 
源代码30 项目: GIFCompressor   文件: BaseTranscoder.java

@Override
public final void setUp(@NonNull MediaFormat desiredOutputFormat) {
    try {
        mEncoder = MediaCodec.createEncoderByType(desiredOutputFormat.getString(MediaFormat.KEY_MIME));
    } catch (IOException e) {
        throw new IllegalStateException(e);
    }
    onConfigureEncoder(desiredOutputFormat, mEncoder);
    onStartEncoder(desiredOutputFormat, mEncoder);
    onStarted(mDataSource.getTrackFormat(), desiredOutputFormat, mEncoder);
}
 
 类所在包
 同包方法