android.media.MediaCodec# release ( ) 源码实例Demo

下面列出了android.media.MediaCodec# release ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: mollyim-android   文件: AudioCodec.java

private MediaCodec createMediaCodec(int bufferSize) throws IOException {
  MediaCodec  mediaCodec  = MediaCodec.createEncoderByType("audio/mp4a-latm");
  MediaFormat mediaFormat = new MediaFormat();

  mediaFormat.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
  mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, SAMPLE_RATE);
  mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNELS);
  mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
  mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
  mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);

  try {
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
  } catch (Exception e) {
    Log.w(TAG, e);
    mediaCodec.release();
    throw new IOException(e);
  }

  return mediaCodec;
}
 
源代码2 项目: bcm-android   文件: AudioCodec.java

private MediaCodec createMediaCodec(int bufferSize) throws IOException {
    MediaCodec mediaCodec = MediaCodec.createEncoderByType("audio/mp4a-latm");
    MediaFormat mediaFormat = new MediaFormat();

    mediaFormat.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
    mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, SAMPLE_RATE);
    mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNELS);
    mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
    mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);

    try {
        mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    } catch (Exception e) {
        Log.w(TAG, e);
        mediaCodec.release();
        throw new IOException(e);
    }

    return mediaCodec;
}
 
源代码3 项目: deltachat-android   文件: AudioCodec.java

private MediaCodec createMediaCodec(Context context, int bufferSize) throws IOException {
  MediaCodec  mediaCodec  = MediaCodec.createEncoderByType("audio/mp4a-latm");
  MediaFormat mediaFormat = new MediaFormat();

  mediaFormat.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
  mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, SAMPLE_RATE);
  mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNELS);
  mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
  mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, Prefs.isHardCompressionEnabled(context)? BIT_RATE_WORSE : BIT_RATE_BALANCED);
  mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);

  try {
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
  } catch (Exception e) {
    Log.w(TAG, e);
    mediaCodec.release();
    throw new IOException(e);
  }

  return mediaCodec;
}
 
源代码4 项目: In77Camera   文件: MediaCodecUtils.java

@TargetApi(MIN_API_LEVEL_AUDIO)
public static int checkMediaCodecAudioEncoderSupport(){
    if(getApiLevel()<MIN_API_LEVEL_AUDIO){
        Log.d(TAG, "checkMediaCodecAudioEncoderSupport: Min API is 16");
        return CODEC_REQ_API_NOT_SATISFIED;
    }
    final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE_AUDIO, TEST_SAMPLE_RATE, 1);
    audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
    audioFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, AudioFormat.CHANNEL_IN_MONO);
    audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, TEST_AUDIO_BIT_RATE);
    audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    MediaCodec mediaCodec;
    try {
        mediaCodec = MediaCodec.createEncoderByType(MIME_TYPE_AUDIO);
        mediaCodec.configure(audioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mediaCodec.start();
        mediaCodec.stop();
        mediaCodec.release();
        mediaCodec = null;
    } catch (Exception ex) {
        Log.e(TAG, "Failed on creation of codec #", ex);
        return CODEC_ERROR;
    }
    return CODEC_SUPPORTED;
}
 

@TargetApi(MIN_API_LEVEL_AUDIO)
public static int checkMediaCodecAudioEncoderSupport(){
    if(getApiLevel()<MIN_API_LEVEL_AUDIO){
        Log.d(TAG, "checkMediaCodecAudioEncoderSupport: Min API is 16");
        return CODEC_REQ_API_NOT_SATISFIED;
    }
    final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE_AUDIO, TEST_SAMPLE_RATE, 1);
    audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
    audioFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, AudioFormat.CHANNEL_IN_MONO);
    audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, TEST_AUDIO_BIT_RATE);
    audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    MediaCodec mediaCodec;
    try {
        mediaCodec = MediaCodec.createEncoderByType(MIME_TYPE_AUDIO);
        mediaCodec.configure(audioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mediaCodec.start();
        mediaCodec.stop();
        mediaCodec.release();
        mediaCodec = null;
    } catch (Exception ex) {
        Log.e(TAG, "Failed on creation of codec #", ex);
        return CODEC_ERROR;
    }
    return CODEC_SUPPORTED;
}
 

/**
 * 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()]);
}
 

/**
 * 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()]);
}
 

@TargetApi(MIN_API_LEVEL_VIDEO)
public static int checkMediaCodecVideoEncoderSupport(){
    if(getApiLevel()<MIN_API_LEVEL_VIDEO){
        Log.d(TAG, "checkMediaCodecVideoEncoderSupport: Min API is 18");
        return CODEC_REQ_API_NOT_SATISFIED;
    }
    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE_VIDEO, TEST_WIDTH, TEST_HEIGHT);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, TEST_VIDEO_BIT_RATE);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, TEST_FRAME_RATE);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, TEST_IFRAME_INTERVAL);
    MediaCodec mediaCodec;
    try {
        mediaCodec = MediaCodec.createEncoderByType(MIME_TYPE_VIDEO);
        mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mediaCodec.createInputSurface();
        mediaCodec.start();
        mediaCodec.stop();
        mediaCodec.release();
        mediaCodec = null;
    } catch (Exception ex) {
        Log.e(TAG, "Failed on creation of codec #", ex);
        return CODEC_ERROR;
    }
    return CODEC_SUPPORTED;
}
 

static void extractThumbnails(final @NonNull MediaInput input,
                              final int thumbnailCount,
                              final int thumbnailResolution,
                              final @NonNull Callback callback)
{
  MediaExtractor extractor     = null;
  MediaCodec     decoder       = null;
  OutputSurface  outputSurface = null;
  try {
    extractor = input.createExtractor();
    MediaFormat mediaFormat = null;
    for (int index = 0; index < extractor.getTrackCount(); ++index) {
      if (extractor.getTrackFormat(index).getString(MediaFormat.KEY_MIME).startsWith("video/")) {
        extractor.selectTrack(index);
        mediaFormat = extractor.getTrackFormat(index);
        break;
      }
    }
    if (mediaFormat != null) {
      final String mime     = mediaFormat.getString(MediaFormat.KEY_MIME);
      final int    rotation = mediaFormat.containsKey(MediaFormat.KEY_ROTATION) ? mediaFormat.getInteger(MediaFormat.KEY_ROTATION) : 0;
      final int    width    = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);
      final int    height   = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
      final int    outputWidth;
      final int    outputHeight;

      if (width < height) {
        outputWidth  = thumbnailResolution;
        outputHeight = height * outputWidth / width;
      } else {
        outputHeight = thumbnailResolution;
        outputWidth  = width * outputHeight / height;
      }

      final int outputWidthRotated;
      final int outputHeightRotated;

      if ((rotation % 180 == 90)) {
        //noinspection SuspiciousNameCombination
        outputWidthRotated = outputHeight;
        //noinspection SuspiciousNameCombination
        outputHeightRotated = outputWidth;
      } else {
        outputWidthRotated  = outputWidth;
        outputHeightRotated = outputHeight;
      }

      Log.i(TAG, "video: " + width + "x" + height + " " + rotation);
      Log.i(TAG, "output: " + outputWidthRotated + "x" + outputHeightRotated);

      outputSurface = new OutputSurface(outputWidthRotated, outputHeightRotated, true);

      decoder = MediaCodec.createDecoderByType(mime);
      decoder.configure(mediaFormat, outputSurface.getSurface(), null, 0);
      decoder.start();

      long duration = 0;

      if (mediaFormat.containsKey(MediaFormat.KEY_DURATION)) {
        duration = mediaFormat.getLong(MediaFormat.KEY_DURATION);
      } else {
        Log.w(TAG, "Video is missing duration!");
      }

      callback.durationKnown(duration);

      doExtract(extractor, decoder, outputSurface, outputWidthRotated, outputHeightRotated, duration, thumbnailCount, callback);
    }
  } catch (IOException | TranscodingException e) {
    Log.w(TAG, e);
    callback.failed();
  } finally {
    if (outputSurface != null) {
      outputSurface.release();
    }
    if (decoder != null) {
      decoder.stop();
      decoder.release();
    }
    if (extractor != null) {
      extractor.release();
    }
  }
}
 

private void feedClipToEncoder( SamplerClip clip ) {

      mLastSampleTime = 0;

      MediaCodec decoder = null;

      MediaExtractor extractor = setupExtractorForClip(clip);
      
      if(extractor == null ) {
         return;
      }
      
      int trackIndex = getVideoTrackIndex(extractor);
      extractor.selectTrack( trackIndex );

      MediaFormat clipFormat = extractor.getTrackFormat( trackIndex );

      if ( clip.getStartTime() != -1 ) {
         extractor.seekTo( clip.getStartTime() * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC );
         clip.setStartTime( extractor.getSampleTime() / 1000 );
      }
      
      try {
         decoder = MediaCodec.createDecoderByType( MediaHelper.MIME_TYPE_AVC );
         mOutputSurface = new OutputSurface();

         decoder.configure( clipFormat, mOutputSurface.getSurface(), null, 0 );
         decoder.start();

         resampleVideo( extractor, decoder, clip );

      } finally {

         if ( mOutputSurface != null ) {
            mOutputSurface.release();
         }
         if ( decoder != null ) {
            decoder.stop();
            decoder.release();
         }

         if ( extractor != null ) {
            extractor.release();
            extractor = null;
         }
      }
   }
 
源代码11 项目: Telegram   文件: MediaCodecRenderer.java

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);
}
 
源代码12 项目: VideoProcessor   文件: AudioUtil.java

/**
 * 需要改变音频速率的情况下,需要先解码->改变速率->编码
 */
public static void decodeToPCM(VideoProcessor.MediaSource audioSource, String outPath, Integer startTimeUs, Integer endTimeUs) throws IOException {
    MediaExtractor extractor = new MediaExtractor();
    audioSource.setDataSource(extractor);
    int audioTrack = VideoUtil.selectTrack(extractor, true);
    extractor.selectTrack(audioTrack);
    if (startTimeUs == null) {
        startTimeUs = 0;
    }
    extractor.seekTo(startTimeUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
    MediaFormat oriAudioFormat = extractor.getTrackFormat(audioTrack);
    int maxBufferSize;
    if (oriAudioFormat.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
        maxBufferSize = oriAudioFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
    } else {
        maxBufferSize = 100 * 1000;
    }
    ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

    //调整音频速率需要重解码音频帧
    MediaCodec decoder = MediaCodec.createDecoderByType(oriAudioFormat.getString(MediaFormat.KEY_MIME));
    decoder.configure(oriAudioFormat, null, null, 0);
    decoder.start();

    boolean decodeDone = false;
    boolean decodeInputDone = false;
    final int TIMEOUT_US = 2500;
    File pcmFile = new File(outPath);
    FileChannel writeChannel = new FileOutputStream(pcmFile).getChannel();
    try {
        while (!decodeDone) {
            if (!decodeInputDone) {
                boolean eof = false;
                int decodeInputIndex = decoder.dequeueInputBuffer(TIMEOUT_US);
                if (decodeInputIndex >= 0) {
                    long sampleTimeUs = extractor.getSampleTime();
                    if (sampleTimeUs == -1) {
                        eof = true;
                    } else if (sampleTimeUs < startTimeUs) {
                        extractor.advance();
                        continue;
                    } else if (endTimeUs != null && sampleTimeUs > endTimeUs) {
                        eof = true;
                    }

                    if (eof) {
                        decodeInputDone = true;
                        decoder.queueInputBuffer(decodeInputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    } else {
                        info.size = extractor.readSampleData(buffer, 0);
                        info.presentationTimeUs = sampleTimeUs;
                        info.flags = extractor.getSampleFlags();
                        ByteBuffer inputBuffer = decoder.getInputBuffer(decodeInputIndex);
                        inputBuffer.put(buffer);
                        CL.it(TAG, "audio decode queueInputBuffer " + info.presentationTimeUs / 1000);
                        decoder.queueInputBuffer(decodeInputIndex, 0, info.size, info.presentationTimeUs, info.flags);
                        extractor.advance();
                    }

                }
            }

            while (!decodeDone) {
                int outputBufferIndex = decoder.dequeueOutputBuffer(info, TIMEOUT_US);
                if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
                    break;
                } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat newFormat = decoder.getOutputFormat();
                    CL.it(TAG, "audio decode newFormat = " + newFormat);
                } else if (outputBufferIndex < 0) {
                    //ignore
                    CL.et(TAG, "unexpected result from audio decoder.dequeueOutputBuffer: " + outputBufferIndex);
                } else {
                    if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
                        decodeDone = true;
                    } else {
                        ByteBuffer decodeOutputBuffer = decoder.getOutputBuffer(outputBufferIndex);
                        CL.it(TAG, "audio decode saveFrame " + info.presentationTimeUs / 1000);
                        writeChannel.write(decodeOutputBuffer);
                    }
                    decoder.releaseOutputBuffer(outputBufferIndex, false);
                }
            }
        }
    } finally {
        writeChannel.close();
        extractor.release();
        decoder.stop();
        decoder.release();
    }
}
 
源代码13 项目: Telegram-FOSS   文件: MediaCodecRenderer.java

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);
}
 

/**
 * Generates a test video file, saving it as VideoChunks.  We generate frames with GL to
 * avoid having to deal with multiple YUV formats.
 *
 * @return true on success, false on "soft" failure
 */
private boolean generateVideoFile(VideoChunks output) {
    if (VERBOSE) Log.d(TAG, "generateVideoFile " + mWidth + "x" + mHeight);
    MediaCodec encoder = null;
    InputSurface inputSurface = 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 false;
        }
        if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
        // 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,
                MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        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);
        output.setMediaFormat(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);
        inputSurface = new InputSurface(encoder.createInputSurface());
        inputSurface.makeCurrent();
        encoder.start();
        generateVideoData(encoder, inputSurface, output);
    } finally {
        if (encoder != null) {
            if (VERBOSE) Log.d(TAG, "releasing encoder");
            encoder.stop();
            encoder.release();
            if (VERBOSE) Log.d(TAG, "released encoder");
        }
        if (inputSurface != null) {
            inputSurface.release();
        }
    }
    return true;
}
 

/**
 * Edits a video file, saving the contents to a new file.  This involves decoding and
 * re-encoding, not to mention conversions between YUV and RGB, and so may be lossy.
 * <p>
 * If we recognize the decoded format we can do this in Java code using the ByteBuffer[]
 * output, but it's not practical to support all OEM formats.  By using a SurfaceTexture
 * for output and a Surface for input, we can avoid issues with obscure formats and can
 * use a fragment shader to do transformations.
 */
private VideoChunks editVideoFile(VideoChunks inputData) {
    if (VERBOSE) Log.d(TAG, "editVideoFile " + mWidth + "x" + mHeight);
    VideoChunks outputData = new VideoChunks();
    MediaCodec decoder = null;
    MediaCodec encoder = null;
    InputSurface inputSurface = null;
    OutputSurface outputSurface = null;
    try {
        MediaFormat inputFormat = inputData.getMediaFormat();
        // Create an encoder format that matches the input format.  (Might be able to just
        // re-use the format used to generate the video, since we want it to be the same.)
        MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
        outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        outputFormat.setInteger(MediaFormat.KEY_BIT_RATE,
                inputFormat.getInteger(MediaFormat.KEY_BIT_RATE));
        outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE,
                inputFormat.getInteger(MediaFormat.KEY_FRAME_RATE));
        outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
                inputFormat.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL));
        outputData.setMediaFormat(outputFormat);
        encoder = MediaCodec.createEncoderByType(MIME_TYPE);
        encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        inputSurface = new InputSurface(encoder.createInputSurface());
        inputSurface.makeCurrent();
        encoder.start();
        // OutputSurface uses the EGL context created by InputSurface.
        decoder = MediaCodec.createDecoderByType(MIME_TYPE);
        outputSurface = new OutputSurface();
        outputSurface.changeFragmentShader(FRAGMENT_SHADER);
        decoder.configure(inputFormat, outputSurface.getSurface(), null, 0);
        decoder.start();
        editVideoData(inputData, decoder, outputSurface, inputSurface, encoder, outputData);
    } finally {
        if (VERBOSE) Log.d(TAG, "shutting down encoder, decoder");
        if (outputSurface != null) {
            outputSurface.release();
        }
        if (inputSurface != null) {
            inputSurface.release();
        }
        if (encoder != null) {
            encoder.stop();
            encoder.release();
        }
        if (decoder != null) {
            decoder.stop();
            decoder.release();
        }
    }
    return outputData;
}
 
源代码16 项目: LiveMultimedia   文件: HWEncoder.java

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);
   	          }
}
 
源代码17 项目: speechutils   文件: EncodedAudioRecorder.java

/**
 * 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 int recorderEncoderLoop(MediaCodec codec, SpeechRecord speechRecord) {
    int status = -1;
    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 numDequeueOutputBufferTimeout = 0;
        int index;
        while (true) {
            if (!doneSubmittingInput) {
                index = codec.dequeueInputBuffer(DEQUEUE_INPUT_BUFFER_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_OUTPUT_BUFFER_TIMEOUT);
            Log.i("enc: out: flags/index: " + info.flags + "/" + index);
            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
                numDequeueOutputBufferTimeout++;
                Log.i("enc: out: INFO_TRY_AGAIN_LATER: " + numDequeueOutputBufferTimeout);
                if (numDequeueOutputBufferTimeout > 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;
                numDequeueOutputBufferTimeout = 0;
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    Log.i("enc: out: EOS");
                    status = 0;
                    break;
                }
            }
        }
        codec.stop();
        codec.release();
        Log.i("stopped and released codec");
    }
    return status;
}
 

/**
 * 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);
    }
}
 
源代码19 项目: AlexaAndroid   文件: EncodedAudioRecorder.java

/**
 * 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();
    }
}
 
源代码20 项目: AlexaAndroid   文件: EncodedAudioRecorder.java

/**
 * 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();
    }
}