/** * Configures encoder and muxer state, and prepares the input Surface. Initializes mEncoder, * mMuxer, mRecordingSurface, mBufferInfo, mTrackIndex, and mMuxerStarted. */ private void configureMediaCodecEncoder() { mBufferInfo = new MediaCodec.BufferInfo(); MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mStreamSize.getWidth(), mStreamSize.getHeight()); /** * Set encoding properties. Failing to specify some of these can cause the MediaCodec * configure() call to throw an exception. */ format.setInteger( MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_BIT_RATE, mEncBitRate); format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL); Log.i(TAG, "configure video encoding format: " + format); // Create/configure a MediaCodec encoder. mEncoder = MediaCodec.createEncoderByType(MIME_TYPE); mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mRecordingSurface = mEncoder.createInputSurface(); mEncoder.start(); String outputFileName = getOutputMediaFileName(); if (outputFileName == null) { throw new IllegalStateException("Failed to get video output file"); } /** * Create a MediaMuxer. We can't add the video track and start() the muxer until the encoder * starts and notifies the new media format. */ try { mMuxer = new MediaMuxer(outputFileName, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException ioe) { throw new IllegalStateException("MediaMuxer creation failed", ioe); } mMuxerStarted = false; }
/** * Configure stream with a size and encoder mode. * * @param size Size of recording stream. * @param useMediaCodec The encoder for this stream to use, either MediaCodec or MediaRecorder. * @param bitRate Bit rate the encoder takes. */ public synchronized void configure(Size size, boolean useMediaCodec, int bitRate) { if (getStreamState() == STREAM_STATE_RECORDING) { throw new IllegalStateException("Stream can only be configured when stream is in IDLE state"); } boolean isConfigChanged = (!mStreamSize.equals(size)) || (mUseMediaCodec != useMediaCodec) || (mEncBitRate != bitRate); mStreamSize = size; mUseMediaCodec = useMediaCodec; mEncBitRate = bitRate; if (mUseMediaCodec) { if (getStreamState() == STREAM_STATE_CONFIGURED) { /** * Stream is already configured, need release encoder and muxer first, then reconfigure only * if configuration is changed. */ if (!isConfigChanged) { /** * TODO: this is only the skeleton, it is tricky to implement because muxer need * reconfigure always. But muxer is closely coupled with MediaCodec for now because muxer * can only be started once format change callback is sent from mediacodec. We need * decouple MediaCodec and Muxer for future. */ } releaseEncoder(); releaseMuxer(); configureMediaCodecEncoder(); } else { configureMediaCodecEncoder(); } } else { // TODO: implement MediaRecoder mode. Log.w(TAG, "MediaRecorder configure is not implemented yet"); } setStreamState(STREAM_STATE_CONFIGURED); }