Java Code Examples for android.media.MediaFormat#createVideoFormat()

The following examples show how to use android.media.MediaFormat#createVideoFormat() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MediaReaper.java    From libcommon with Apache License 2.0 6 votes vote down vote up
@Override
protected MediaFormat createOutputFormat(final byte[] csd, final int size,
	final int ix0, final int ix1, final int ix2) {
	
	if (DEBUG) Log.v(TAG, "VideoReaper#createOutputFormat");
	final MediaFormat outFormat;
	if (ix0 >= 0) {
		outFormat = MediaFormat.createVideoFormat(MIME_AVC, mWidth, mHeight);
		final ByteBuffer csd0 = ByteBuffer.allocateDirect(ix1 - ix0)
			.order(ByteOrder.nativeOrder());
		csd0.put(csd, ix0, ix1 - ix0);
		csd0.flip();
		outFormat.setByteBuffer("csd-0", csd0);
		if (ix1 > ix0) {
			final int sz = (ix2 > ix1) ? (ix2 - ix1) : (size - ix1);
			final ByteBuffer csd1 = ByteBuffer.allocateDirect(sz)
				.order(ByteOrder.nativeOrder());
			csd1.put(csd, ix1, sz);
			csd1.flip();
			outFormat.setByteBuffer("csd-1", csd1);
		}
	} else {
		throw new RuntimeException("unexpected csd data came.");
	}
	return outFormat;
}
 
Example 2
Source File: ScreenRecordThread.java    From ScreenCapture with MIT License 6 votes vote down vote up
private void prepareEncoder() {
    MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, mWidth, mHeight);
    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);

    Log.d(TAG, "created video format: " + format);
    try {
        mEncoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
    } catch (IOException e) {
        e.printStackTrace();
    }
    mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mSurface = mEncoder.createInputSurface();
    Log.d(TAG, "created input surface: " + mSurface);
    mEncoder.start();
}
 
Example 3
Source File: EncoderUtilsTest.java    From sdl_java_suite with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
public void testGetCodecSpecificDataForAVC() {
    // example of SPS NAL unit with 4-byte start code
    byte[] sps = new byte[] {
            0x00, 0x00, 0x00, 0x01,
            0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
            0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
            0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60
    };
    // example of PPS NAL unit with 4-byte start code
    byte[] pps = new byte[] {
            0x00, 0x00, 0x00, 0x01,
            0x68, (byte)0xC8, 0x42, 0x0F, 0x13, 0x20
    };

    ByteBuffer spsByteBuffer = ByteBuffer.allocate(sps.length);
    spsByteBuffer.put(sps);
    spsByteBuffer.flip();

    ByteBuffer ppsByteBuffer = ByteBuffer.allocate(pps.length);
    ppsByteBuffer.put(pps);
    ppsByteBuffer.flip();

    MediaFormat format = MediaFormat.createVideoFormat("video/avc", 16, 16);
    format.setByteBuffer("csd-0", spsByteBuffer);
    format.setByteBuffer("csd-1", ppsByteBuffer);

    byte[] result = EncoderUtils.getCodecSpecificData(format);
    assertNotNull(result);

    byte[] expected = new byte[sps.length + pps.length];
    System.arraycopy(sps, 0, expected, 0, sps.length);
    System.arraycopy(pps, 0, expected, sps.length, pps.length);
    assertTrue("Output codec specific data doesn't match", Arrays.equals(expected, result));
}
 
Example 4
Source File: VideoCodecTask.java    From MultiMediaSample with Apache License 2.0 6 votes vote down vote up
/**
 * 初始化编码器
 */

private void initMediaEncode() {
    getEncodeColor();
    try {
        MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, mDstWidth, mDstHeight);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 1024 * 512);
        format.setInteger(MediaFormat.KEY_FRAME_RATE, 27);
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, mVideoEncodeColor);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);

        mMediaEncode = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
        mMediaEncode.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (mMediaEncode == null) {
        Log.e(TAG, "create mMediaEncode failed");
        return;
    }
    mMediaEncode.start();

}
 
Example 5
Source File: ScreenRecordActivity.java    From grafika with Apache License 2.0 6 votes vote down vote up
@RequiresApi(api = Build.VERSION_CODES.M)
private void prepareVideoEncoder(int width, int height) {
  MediaFormat format = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, width, height);
  int frameRate = 30; // 30 fps

  // Set some required properties. The media codec may fail if these aren't defined.
  format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
          MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
  format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000); // 6Mbps
  format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
  format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate);
  format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000 / frameRate);
  format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
  format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 1 seconds between I-frames

  // Create a MediaCodec encoder and configure it. Get a Surface we can use for recording into.
  try {
    videoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
    videoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    inputSurface = videoEncoder.createInputSurface();
    videoEncoder.setCallback(encoderCallback);
    videoEncoder.start();
  } catch (IOException e) {
    releaseEncoders();
  }
}
 
Example 6
Source File: H264Decoder.java    From DeviceConnect-Android with MIT License 6 votes vote down vote up
@Override
protected MediaCodec createMediaCodec() throws IOException {
    MediaFormat format = MediaFormat.createVideoFormat(mMimeType, 0, 0);
    if (mCsd0 != null) {
        format.setByteBuffer("csd-0", mCsd0);
    }

    if (mCsd1 != null) {
        format.setByteBuffer("csd-1", mCsd1);
    }

    MediaCodec mediaCodec = MediaCodec.createDecoderByType(mMimeType);
    mediaCodec.configure(format, getSurface(), null, 0);
    mediaCodec.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
    mediaCodec.start();
    return mediaCodec;
}
 
Example 7
Source File: RecordUtil.java    From WeiXinRecordedDemo with MIT License 6 votes vote down vote up
private void initVideoMediaCodec()throws Exception{
    MediaFormat mediaFormat;
    if(rotation==90 || rotation==270){
        //设置视频宽高
        mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, videoHeight, videoWidth);
    }else{
        mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, videoWidth, videoHeight);
    }
    //图像数据格式 YUV420
    mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
    //码率
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, videoWidth*videoHeight*3);
    //每秒30帧
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
    //1秒一个关键帧
    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
    videoMediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
    videoMediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    videoMediaCodec.start();
}
 
Example 8
Source File: MediaCodecUtils.java    From Fatigue-Detection with MIT License 5 votes vote down vote up
@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;
}
 
Example 9
Source File: VideoEncodeConfig.java    From ScreenCapture with MIT License 5 votes vote down vote up
MediaFormat toFormat() {
    MediaFormat format = MediaFormat.createVideoFormat(mimeType, width, height);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, framerate);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iframeInterval);
    if (codecProfileLevel != null && codecProfileLevel.profile != 0 && codecProfileLevel.level != 0) {
        format.setInteger(MediaFormat.KEY_PROFILE, codecProfileLevel.profile);
        format.setInteger("level", codecProfileLevel.level);
    }
    // maybe useful
    // format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 10_000_000);
    return format;
}
 
Example 10
Source File: ScreenRecoder.java    From ScreenRecoder with MIT License 5 votes vote down vote up
@Override
public void run() {
	MediaFormat format = MediaFormat.createVideoFormat("video/avc",
			mWidth, mHeight);
	format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
			MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
	format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
	format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
	format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
			I_FRAME_INTERVAL);

	MediaCodec codec = MediaCodec.createEncoderByType("video/avc");
	codec.configure(format, null, null,
			MediaCodec.CONFIGURE_FLAG_ENCODE);
	Surface surface = codec.createInputSurface();
	codec.start();

	VirtualDisplay virtualDisplay = mDisplayManager
			.createVirtualDisplay(DISPLAY_NAME, mWidth, mHeight,
					mDensityDpi, surface,
					DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC);
	
	if (virtualDisplay != null) {
		stream(codec);
		virtualDisplay.release();
	}

	codec.signalEndOfInputStream();
	codec.stop();
}
 
Example 11
Source File: MediaUtil.java    From EZFilter with MIT License 5 votes vote down vote up
/**
 * 创建视频MediaFormat[mp4]
 *
 * @param w           视频宽度
 * @param h           视频高度
 * @param bitrate     视频码率
 * @param colorFormat 颜色格式参考
 *                    {@link MediaCodecInfo.CodecCapabilities#COLOR_FormatYUV420SemiPlanar}
 *                    {@link MediaCodecInfo.CodecCapabilities#COLOR_FormatYUV420Planar}
 *                    {@link MediaCodecInfo.CodecCapabilities#COLOR_FormatSurface}
 * @return
 */
public static MediaFormat createVideoFormat(int w, int h, int bitrate, int colorFormat) {
    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE_MP4, w, h);
    // 数据来源
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
    // 视频bit率
    format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
    // 帧率
    format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
    // 设置关键帧时间间隔(单位为秒)表示:每隔多长时间有一个关键帧
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL);
    return format;
}
 
Example 12
Source File: FakeVideoEncoder.java    From libcommon with Apache License 2.0 5 votes vote down vote up
/**
	 * Muxer初期化用のMediaFormatを生成する
	 * @param csd
	 * @param size
	 * @param ix0
	 * @param ix1
	 * @param ix2
	 * @return
	 */
	@Override
	protected MediaFormat createOutputFormat(final String mime,
		final byte[] csd, final int size,
		final int ix0, final int ix1, final int ix2) {
		
//		if (DEBUG) Log.v(TAG, "createOutputFormat:");
		final MediaFormat outFormat;
        if (ix0 >= 0) {
            outFormat = MediaFormat.createVideoFormat(mime, mWidth, mHeight);
        	final ByteBuffer csd0 = ByteBuffer.allocateDirect(ix1 - ix0)
        		.order(ByteOrder.nativeOrder());
        	csd0.put(csd, ix0, ix1 - ix0);
        	csd0.flip();
            outFormat.setByteBuffer("csd-0", csd0);
//			if (DEBUG) BufferHelper.dump("sps", csd0, 0, csd0 != null ? csd0.capacity() : 0);
            if (ix1 > ix0) {
				final int sz = (ix2 > ix1) ? (ix2 - ix1) : (size - ix1);
            	final ByteBuffer csd1 = ByteBuffer.allocateDirect(sz)
            		.order(ByteOrder.nativeOrder());
            	csd1.put(csd, ix1, sz);
            	csd1.flip();
                outFormat.setByteBuffer("csd-1", csd1);
//				if (DEBUG) BufferHelper.dump("pps", csd1, 0, csd1 != null ? csd1.capacity() : 0);
            }
        } else {
        	throw new RuntimeException("unexpected csd data came.");
        }
//		if (DEBUG) Log.v(TAG, "createOutputFormat:result=" + outFormat);
        return outFormat;
	}
 
Example 13
Source File: SurfaceEncoder.java    From AAVT with Apache License 2.0 5 votes vote down vote up
protected MediaFormat convertVideoConfigToFormat(MediaConfig.Video config){
    MediaFormat format=MediaFormat.createVideoFormat(config.mime,config.width,config.height);
    format.setInteger(MediaFormat.KEY_BIT_RATE,config.bitrate);
    format.setInteger(MediaFormat.KEY_FRAME_RATE,config.frameRate);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,config.iframe);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    return format;
}
 
Example 14
Source File: H264Stream.java    From VideoMeeting with Apache License 2.0 5 votes vote down vote up
/**
     * 初始化并启动编码器
     */
    private void initMediaCodec() {
        int dgree = getDgree();
        int framerate = 15;
        int bitrate = 2 * width * height * framerate / 20;
        debugger = EncoderDebugger.debug(App.getInstance().getApplicationContext(), width, height);
        byte[] pps = Base64.decode(debugger.getB64PPS(), Base64.NO_WRAP);
        byte[] sps = Base64.decode(debugger.getB64SPS(), Base64.NO_WRAP);
        // 设置pps和sps
        ((H264Packetizer) mPacketizer).setStreamParameters(pps, sps);
        mConvertor = debugger.getNV21Convertor();
        try {
            mMediaCodec = MediaCodec.createByCodecName(debugger.getEncoderName());
            MediaFormat mediaFormat;
            if (dgree == 0) {
                // FIXME 将height和width颠倒就花屏了,而不颠倒vlc上显示的是颠倒的
//                mediaFormat = MediaFormat.createVideoFormat("video/avc", height, width);
                mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
            } else {
                mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
            }
            mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
            mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, framerate);
            mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                    debugger.getEncoderColorFormat());
            mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
            mMediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            mMediaCodec.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
Example 15
Source File: CodecWrapper.java    From letv with Apache License 2.0 5 votes vote down vote up
public int createDecoder(int videoWidth, int videoHeight, Surface surface) throws IOException {
    Log.d(LOG_TAG, "start create decoder, videoWidth:" + String.valueOf(videoWidth) + "videoHeight:" + String.valueOf(videoHeight));
    if (videoWidth <= 0 || videoHeight <= 0) {
        Log.d(LOG_TAG, "invalid width or height");
        return -1;
    }
    this.mWidth = videoWidth;
    this.mHeight = videoHeight;
    this.mSurface = surface;
    this.codec = MediaCodec.createDecoderByType("video/avc");
    if (this.codec == null) {
        Log.d(LOG_TAG, "Hardware codec is not available");
        return -1;
    }
    try {
        this.format = MediaFormat.createVideoFormat("video/avc", videoWidth, videoHeight);
        Log.d(LOG_TAG, "configure mediacodec");
        this.codec.configure(this.format, surface, null, 0);
        this.codec.setVideoScalingMode(1);
        Log.d(LOG_TAG, "start mediacodec");
        this.codec.start();
        Log.d(LOG_TAG, "get input and output buffer");
        this.codecInputBuffers = this.codec.getInputBuffers();
        this.codecOutputBuffers = this.codec.getOutputBuffers();
        return 1;
    } catch (IllegalStateException e) {
        Log.d(LOG_TAG, "Exception catched in createDecoder");
        return -1;
    }
}
 
Example 16
Source File: CircularEncoder.java    From pause-resume-video-recording with Apache License 2.0 4 votes vote down vote up
/**
 * Configures encoder, and prepares the input Surface.
 *
 * @param width Width of encoded video, in pixels.  Should be a multiple of 16.
 * @param height Height of encoded video, in pixels.  Usually a multiple of 16 (1080 is ok).
 * @param bitRate Target bit rate, in bits.
 * @param frameRate Expected frame rate.
 * @param desiredSpanSec How many seconds of video we want to have in our buffer at any time.
 */
public CircularEncoder(int width, int height, int bitRate, int frameRate, int desiredSpanSec,
        Callback cb) throws IOException {
    // The goal is to size the buffer so that we can accumulate N seconds worth of video,
    // where N is passed in as "desiredSpanSec".  If the codec generates data at roughly
    // the requested bit rate, we can compute it as time * bitRate / bitsPerByte.
    //
    // Sync frames will appear every (frameRate * IFRAME_INTERVAL) frames.  If the frame
    // rate is higher or lower than expected, various calculations may not work out right.
    //
    // Since we have to start muxing from a sync frame, we want to ensure that there's
    // room for at least one full GOP in the buffer, preferrably two.
    if (desiredSpanSec < IFRAME_INTERVAL * 2) {
        throw new RuntimeException("Requested time span is too short: " + desiredSpanSec +
                " vs. " + (IFRAME_INTERVAL * 2));
    }
    CircularEncoderBuffer encBuffer = new CircularEncoderBuffer(bitRate, frameRate,
            desiredSpanSec);

    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height);

    // 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, bitRate);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
    if (VERBOSE) Log.d(TAG, "format: " + format);

    // Create a MediaCodec encoder, and configure it with our format.  Get a Surface
    // we can use for input and wrap it with a class that handles the EGL work.
    mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
    mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mInputSurface = mEncoder.createInputSurface();
    mEncoder.start();

    // Start the encoder thread last.  That way we're sure it can see all of the state
    // we've initialized.
    mEncoderThread = new EncoderThread(mEncoder, encBuffer, cb);
    mEncoderThread.start();
    mEncoderThread.waitUntilReady();
}
 
Example 17
Source File: VideoAppendEncodeThread.java    From VideoProcessor with Apache License 2.0 4 votes vote down vote up
private void doEncode() throws IOException {
        MediaFormat inputFormat = mExtractor.getTrackFormat(mVideoIndex);
        //初始化编码器
        int frameRate = inputFormat.containsKey(MediaFormat.KEY_FRAME_RATE) ? inputFormat.getInteger(inputFormat.KEY_FRAME_RATE) : DEFAULT_FRAME_RATE;
        MediaFormat outputFormat = MediaFormat.createVideoFormat(VideoProcessor.OUTPUT_MIME_TYPE, mResultWidth, mResultHeight);
        outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitrate);
        outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
        outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, mIFrameInterval);

        mEncoder = MediaCodec.createEncoderByType(VideoProcessor.OUTPUT_MIME_TYPE);
        mEncoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mSurface = mEncoder.createInputSurface();

//        mInputSurface = new InputSurface(encodeSurface);
//        mInputSurface.makeCurrent();
        mEncoder.start();
        mEglContextLatch.countDown();

        boolean signalEncodeEnd = false;
        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        int encodeTryAgainCount = 0;
        //开始编码
        //输出
        while (true) {
            if (mDecodeDone.get() && !signalEncodeEnd) {
                signalEncodeEnd = true;
                mEncoder.signalEndOfInputStream();
            }
            int outputBufferIndex = mEncoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
            CL.i("encode outputBufferIndex = " + outputBufferIndex);
            if (signalEncodeEnd && outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
                encodeTryAgainCount++;
                if (encodeTryAgainCount > 10) {
                    //三星S8上出现signalEndOfInputStream之后一直tryAgain的问题
                    CL.e("INFO_TRY_AGAIN_LATER 10 times,force End!");
                    break;
                }
            } else {
                encodeTryAgainCount = 0;
            }
            if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
                continue;
            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                MediaFormat newFormat = mEncoder.getOutputFormat();
                CL.i("encode newFormat = " + newFormat);
            } else if (outputBufferIndex < 0) {
                //ignore
                CL.e("unexpected result from decoder.dequeueOutputBuffer: " + outputBufferIndex);
            } else {
                //编码数据可用
                ByteBuffer outputBuffer = mEncoder.getOutputBuffer(outputBufferIndex);
                info.presentationTimeUs += mBaseMuxerFrameTimeUs;
                if (!mIsFirst && info.flags == MediaCodec.BUFFER_FLAG_CODEC_CONFIG) {
                    //非第一个片段跳过写入Config
                    continue;
                }
                if (!mIsLast && info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
                    //非最后一个片段不写入End
                    CL.i("encoderDone");
                    mEncoder.releaseOutputBuffer(outputBufferIndex, false);
                    break;
                }
                if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM && info.presentationTimeUs < 0) {
                    info.presentationTimeUs = 0;
                }
                CL.i("writeSampleData,size:" + info.size + " time:" + info.presentationTimeUs / 1000 + " flag:" + info.flags);
                mMuxer.writeSampleData(mMuxerVideoTrackIndex, outputBuffer, info);
                if (mLastFrametimeUs < info.presentationTimeUs) {
                    mLastFrametimeUs = info.presentationTimeUs;
                }
                mEncoder.releaseOutputBuffer(outputBufferIndex, false);
                if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
                    CL.i("encoderDone");
                    break;
                }
            }
        }
    }
 
Example 18
Source File: CircularEncoder.java    From grafika with Apache License 2.0 4 votes vote down vote up
/**
 * Configures encoder, and prepares the input Surface.
 *
 * @param width Width of encoded video, in pixels.  Should be a multiple of 16.
 * @param height Height of encoded video, in pixels.  Usually a multiple of 16 (1080 is ok).
 * @param bitRate Target bit rate, in bits.
 * @param frameRate Expected frame rate.
 * @param desiredSpanSec How many seconds of video we want to have in our buffer at any time.
 */
public CircularEncoder(int width, int height, int bitRate, int frameRate, int desiredSpanSec,
        Callback cb) throws IOException {
    // The goal is to size the buffer so that we can accumulate N seconds worth of video,
    // where N is passed in as "desiredSpanSec".  If the codec generates data at roughly
    // the requested bit rate, we can compute it as time * bitRate / bitsPerByte.
    //
    // Sync frames will appear every (frameRate * IFRAME_INTERVAL) frames.  If the frame
    // rate is higher or lower than expected, various calculations may not work out right.
    //
    // Since we have to start muxing from a sync frame, we want to ensure that there's
    // room for at least one full GOP in the buffer, preferrably two.
    if (desiredSpanSec < IFRAME_INTERVAL * 2) {
        throw new RuntimeException("Requested time span is too short: " + desiredSpanSec +
                " vs. " + (IFRAME_INTERVAL * 2));
    }
    CircularEncoderBuffer encBuffer = new CircularEncoderBuffer(bitRate, frameRate,
            desiredSpanSec);

    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height);

    // 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, bitRate);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
    if (VERBOSE) Log.d(TAG, "format: " + format);

    // Create a MediaCodec encoder, and configure it with our format.  Get a Surface
    // we can use for input and wrap it with a class that handles the EGL work.
    mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
    mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mInputSurface = mEncoder.createInputSurface();
    mEncoder.start();

    // Start the encoder thread last.  That way we're sure it can see all of the state
    // we've initialized.
    mEncoderThread = new EncoderThread(mEncoder, encBuffer, cb);
    mEncoderThread.start();
    mEncoderThread.waitUntilReady();
}
 
Example 19
Source File: EncoderUtilsTest.java    From sdl_java_suite with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
public void testGetCodecSpecificDataForUnknownCodec() {
    MediaFormat format = MediaFormat.createVideoFormat("video/raw", 16, 16);
    byte[] result = EncoderUtils.getCodecSpecificData(format);
    assertNull("For unsupported codec, getCodecSpecificData should return null", result);
}
 
Example 20
Source File: DecodeEditEncodeTest.java    From Android-MediaCodec-Examples with Apache License 2.0 4 votes vote down vote up
/**
 * 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;
}