aboutsummaryrefslogtreecommitdiffstats
path: root/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format
diff options
context:
space:
mode:
Diffstat (limited to 'libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format')
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android16By9FormatStrategy.java88
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android720pFormatStrategy.java90
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/ExportPreset960x540Strategy.java44
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatExtraConstants.java56
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatPresets.java80
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategy.java39
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategyPresets.java73
-rw-r--r--libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/OutputFormatUnavailableException.java22
8 files changed, 492 insertions, 0 deletions
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android16By9FormatStrategy.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android16By9FormatStrategy.java
new file mode 100644
index 000000000..faf303127
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android16By9FormatStrategy.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+import android.util.Log;
+
+class Android16By9FormatStrategy implements MediaFormatStrategy {
+ public static final int AUDIO_BITRATE_AS_IS = -1;
+ public static final int AUDIO_CHANNELS_AS_IS = -1;
+ public static final int SCALE_720P = 5;
+ private static final String TAG = "Android16By9FormatStrategy";
+ private final int mScale;
+ private final int mVideoBitrate;
+ private final int mAudioBitrate;
+ private final int mAudioChannels;
+
+ public Android16By9FormatStrategy(int scale, int videoBitrate) {
+ this(scale, videoBitrate, AUDIO_BITRATE_AS_IS, AUDIO_CHANNELS_AS_IS);
+ }
+
+ public Android16By9FormatStrategy(int scale, int videoBitrate, int audioBitrate, int audioChannels) {
+ mScale = scale;
+ mVideoBitrate = videoBitrate;
+ mAudioBitrate = audioBitrate;
+ mAudioChannels = audioChannels;
+ }
+
+ @Override
+ public MediaFormat createVideoOutputFormat(MediaFormat inputFormat) {
+ int width = inputFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int height = inputFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ int targetLonger = mScale * 16 * 16;
+ int targetShorter = mScale * 16 * 9;
+ int longer, shorter, outWidth, outHeight;
+ if (width >= height) {
+ longer = width;
+ shorter = height;
+ outWidth = targetLonger;
+ outHeight = targetShorter;
+ } else {
+ shorter = width;
+ longer = height;
+ outWidth = targetShorter;
+ outHeight = targetLonger;
+ }
+ if (longer * 9 != shorter * 16) {
+ throw new OutputFormatUnavailableException("This video is not 16:9, and is not able to transcode. (" + width + "x" + height + ")");
+ }
+ if (shorter <= targetShorter) {
+ Log.d(TAG, "This video's height is less or equal to " + targetShorter + ", pass-through. (" + width + "x" + height + ")");
+ return null;
+ }
+ MediaFormat format = MediaFormat.createVideoFormat("video/avc", outWidth, outHeight);
+ // From Nexus 4 Camera in 720p
+ format.setInteger(MediaFormat.KEY_BIT_RATE, mVideoBitrate);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
+ format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 3);
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
+ return format;
+ }
+
+ @Override
+ public MediaFormat createAudioOutputFormat(MediaFormat inputFormat) {
+ if (mAudioBitrate == AUDIO_BITRATE_AS_IS || mAudioChannels == AUDIO_CHANNELS_AS_IS) return null;
+
+ // Use original sample rate, as resampling is not supported yet.
+ final MediaFormat format = MediaFormat.createAudioFormat(MediaFormatExtraConstants.MIMETYPE_AUDIO_AAC,
+ inputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE), mAudioChannels);
+ format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, mAudioBitrate);
+ return format;
+ }
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android720pFormatStrategy.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android720pFormatStrategy.java
new file mode 100644
index 000000000..dc59caa1d
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/Android720pFormatStrategy.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+import android.util.Log;
+
+class Android720pFormatStrategy implements MediaFormatStrategy {
+ public static final int AUDIO_BITRATE_AS_IS = -1;
+ public static final int AUDIO_CHANNELS_AS_IS = -1;
+ private static final String TAG = "720pFormatStrategy";
+ private static final int LONGER_LENGTH = 1280;
+ private static final int SHORTER_LENGTH = 720;
+ private static final int DEFAULT_VIDEO_BITRATE = 8000 * 1000; // From Nexus 4 Camera in 720p
+ private final int mVideoBitrate;
+ private final int mAudioBitrate;
+ private final int mAudioChannels;
+
+ public Android720pFormatStrategy() {
+ this(DEFAULT_VIDEO_BITRATE);
+ }
+
+ public Android720pFormatStrategy(int videoBitrate) {
+ this(videoBitrate, AUDIO_BITRATE_AS_IS, AUDIO_CHANNELS_AS_IS);
+ }
+
+ public Android720pFormatStrategy(int videoBitrate, int audioBitrate, int audioChannels) {
+ mVideoBitrate = videoBitrate;
+ mAudioBitrate = audioBitrate;
+ mAudioChannels = audioChannels;
+ }
+
+ @Override
+ public MediaFormat createVideoOutputFormat(MediaFormat inputFormat) {
+ int width = inputFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int height = inputFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ int longer, shorter, outWidth, outHeight;
+ if (width >= height) {
+ longer = width;
+ shorter = height;
+ outWidth = LONGER_LENGTH;
+ outHeight = SHORTER_LENGTH;
+ } else {
+ shorter = width;
+ longer = height;
+ outWidth = SHORTER_LENGTH;
+ outHeight = LONGER_LENGTH;
+ }
+ if (longer * 9 != shorter * 16) {
+ throw new OutputFormatUnavailableException("This video is not 16:9, and is not able to transcode. (" + width + "x" + height + ")");
+ }
+ if (shorter <= SHORTER_LENGTH) {
+ Log.d(TAG, "This video is less or equal to 720p, pass-through. (" + width + "x" + height + ")");
+ return null;
+ }
+ MediaFormat format = MediaFormat.createVideoFormat("video/avc", outWidth, outHeight);
+ // From Nexus 4 Camera in 720p
+ format.setInteger(MediaFormat.KEY_BIT_RATE, mVideoBitrate);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
+ format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 3);
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
+ return format;
+ }
+
+ @Override
+ public MediaFormat createAudioOutputFormat(MediaFormat inputFormat) {
+ if (mAudioBitrate == AUDIO_BITRATE_AS_IS || mAudioChannels == AUDIO_CHANNELS_AS_IS) return null;
+
+ // Use original sample rate, as resampling is not supported yet.
+ final MediaFormat format = MediaFormat.createAudioFormat(MediaFormatExtraConstants.MIMETYPE_AUDIO_AAC,
+ inputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE), mAudioChannels);
+ format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, mAudioBitrate);
+ return format;
+ }
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/ExportPreset960x540Strategy.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/ExportPreset960x540Strategy.java
new file mode 100644
index 000000000..56d9a7d34
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/ExportPreset960x540Strategy.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+import android.media.MediaFormat;
+import android.util.Log;
+
+/**
+* Created by yuya.tanaka on 2014/11/20.
+*/
+class ExportPreset960x540Strategy implements MediaFormatStrategy {
+ private static final String TAG = "ExportPreset960x540Strategy";
+
+ @Override
+ public MediaFormat createVideoOutputFormat(MediaFormat inputFormat) {
+ // TODO: detect non-baseline profile and throw exception
+ int width = inputFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int height = inputFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ MediaFormat outputFormat = MediaFormatPresets.getExportPreset960x540(width, height);
+ int outWidth = outputFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int outHeight = outputFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ Log.d(TAG, String.format("inputFormat: %dx%d => outputFormat: %dx%d", width, height, outWidth, outHeight));
+ return outputFormat;
+ }
+
+ @Override
+ public MediaFormat createAudioOutputFormat(MediaFormat inputFormat) {
+ // TODO
+ return null;
+ }
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatExtraConstants.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatExtraConstants.java
new file mode 100644
index 000000000..7f34adc97
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatExtraConstants.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+public class MediaFormatExtraConstants {
+ // from MediaFormat of API level >= 21, but might be usable in older APIs as native code implementation exists.
+ // https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright/ACodec.cpp#2621
+ // NOTE: native code enforces baseline profile.
+ // https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright/ACodec.cpp#2638
+ /** For encoder parameter. Use value of MediaCodecInfo.CodecProfileLevel.AVCProfile* . */
+ public static final String KEY_PROFILE = "profile";
+
+ // from https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright/ACodec.cpp#2623
+ /** For encoder parameter. Use value of MediaCodecInfo.CodecProfileLevel.AVCLevel* . */
+ public static final String KEY_LEVEL = "level";
+
+ // from https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright/MediaCodec.cpp#2197
+ /** Included in MediaFormat from {@link android.media.MediaExtractor#getTrackFormat(int)}. Value is {@link java.nio.ByteBuffer}. */
+ public static final String KEY_AVC_SPS = "csd-0";
+ /** Included in MediaFormat from {@link android.media.MediaExtractor#getTrackFormat(int)}. Value is {@link java.nio.ByteBuffer}. */
+ public static final String KEY_AVC_PPS = "csd-1";
+
+ /**
+ * For decoder parameter and included in MediaFormat from {@link android.media.MediaExtractor#getTrackFormat(int)}.
+ * Decoder rotates specified degrees before rendering video to surface.
+ * NOTE: Only included in track format of API &gt;= 21.
+ */
+ public static final String KEY_ROTATION_DEGREES = "rotation-degrees";
+
+ // Video formats
+ // from MediaFormat of API level >= 21
+ public static final String MIMETYPE_VIDEO_AVC = "video/avc";
+ public static final String MIMETYPE_VIDEO_H263 = "video/3gpp";
+ public static final String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
+
+ // Audio formats
+ // from MediaFormat of API level >= 21
+ public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
+
+ private MediaFormatExtraConstants() {
+ throw new RuntimeException();
+ }
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatPresets.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatPresets.java
new file mode 100644
index 000000000..086bcd3f3
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatPresets.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+
+// Refer for example: https://gist.github.com/wobbals/3990442
+// Refer for preferred parameters: https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/UsingHTTPLiveStreaming/UsingHTTPLiveStreaming.html#//apple_ref/doc/uid/TP40008332-CH102-SW8
+// Refer for available keys: (ANDROID ROOT)/media/libstagefright/ACodec.cpp
+public class MediaFormatPresets {
+ private static final int LONGER_LENGTH_960x540 = 960;
+
+ private MediaFormatPresets() {
+ }
+
+ // preset similar to iOS SDK's AVAssetExportPreset960x540
+ @Deprecated
+ public static MediaFormat getExportPreset960x540() {
+ MediaFormat format = MediaFormat.createVideoFormat("video/avc", 960, 540);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, 5500 * 1000);
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
+ format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
+ return format;
+ }
+
+ /**
+ * Preset similar to iOS SDK's AVAssetExportPreset960x540.
+ * Note that encoding resolutions of this preset are not supported in all devices e.g. Nexus 4.
+ * On unsupported device encoded video stream will be broken without any exception.
+ * @param originalWidth Input video width.
+ * @param originalHeight Input video height.
+ * @return MediaFormat instance, or null if pass through.
+ */
+ public static MediaFormat getExportPreset960x540(int originalWidth, int originalHeight) {
+ int longerLength = Math.max(originalWidth, originalHeight);
+ int shorterLength = Math.min(originalWidth, originalHeight);
+
+ if (longerLength <= LONGER_LENGTH_960x540) return null; // don't upscale
+
+ int residue = LONGER_LENGTH_960x540 * shorterLength % longerLength;
+ if (residue != 0) {
+ double ambiguousShorter = (double) LONGER_LENGTH_960x540 * shorterLength / longerLength;
+ throw new OutputFormatUnavailableException(String.format(
+ "Could not fit to integer, original: (%d, %d), scaled: (%d, %f)",
+ longerLength, shorterLength, LONGER_LENGTH_960x540, ambiguousShorter));
+ }
+
+ int scaledShorter = LONGER_LENGTH_960x540 * shorterLength / longerLength;
+ int width, height;
+ if (originalWidth >= originalHeight) {
+ width = LONGER_LENGTH_960x540;
+ height = scaledShorter;
+ } else {
+ width = scaledShorter;
+ height = LONGER_LENGTH_960x540;
+ }
+
+ MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, 5500 * 1000);
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
+ format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
+ return format;
+ }
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategy.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategy.java
new file mode 100644
index 000000000..1aa8f6dc9
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategy.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+import android.media.MediaFormat;
+
+public interface MediaFormatStrategy {
+
+ /**
+ * Returns preferred video format for encoding.
+ *
+ * @param inputFormat MediaFormat from MediaExtractor, contains csd-0/csd-1.
+ * @return null for passthrough.
+ * @throws OutputFormatUnavailableException if input could not be transcoded because of restrictions.
+ */
+ public MediaFormat createVideoOutputFormat(MediaFormat inputFormat);
+
+ /**
+ * Caution: this method should return null currently.
+ *
+ * @return null for passthrough.
+ * @throws OutputFormatUnavailableException if input could not be transcoded because of restrictions.
+ */
+ public MediaFormat createAudioOutputFormat(MediaFormat inputFormat);
+
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategyPresets.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategyPresets.java
new file mode 100644
index 000000000..30802586b
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategyPresets.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+public class MediaFormatStrategyPresets {
+ public static final int AUDIO_BITRATE_AS_IS = -1;
+ public static final int AUDIO_CHANNELS_AS_IS = -1;
+
+ /**
+ * @deprecated Use {@link #createExportPreset960x540Strategy()}.
+ */
+ @Deprecated
+ public static final MediaFormatStrategy EXPORT_PRESET_960x540 = new ExportPreset960x540Strategy();
+
+ /**
+ * Preset based on Nexus 4 camera recording with 720p quality.
+ * This preset is ensured to work on any Android &gt;=4.3 devices by Android CTS (if codec is available).
+ * Default bitrate is 8Mbps. {@link #createAndroid720pStrategy(int)} to specify bitrate.
+ */
+ public static MediaFormatStrategy createAndroid720pStrategy() {
+ return new Android720pFormatStrategy();
+ }
+
+ /**
+ * Preset based on Nexus 4 camera recording with 720p quality.
+ * This preset is ensured to work on any Android &gt;=4.3 devices by Android CTS (if codec is available).
+ * Audio track will be copied as-is.
+ *
+ * @param bitrate Preferred bitrate for video encoding.
+ */
+ public static MediaFormatStrategy createAndroid720pStrategy(int bitrate) {
+ return new Android720pFormatStrategy(bitrate);
+ }
+
+ /**
+ * Preset based on Nexus 4 camera recording with 720p quality.
+ * This preset is ensured to work on any Android &gt;=4.3 devices by Android CTS (if codec is available).
+ * <br>
+ * Note: audio transcoding is experimental feature.
+ *
+ * @param bitrate Preferred bitrate for video encoding.
+ * @param audioBitrate Preferred bitrate for audio encoding.
+ * @param audioChannels Output audio channels.
+ */
+ public static MediaFormatStrategy createAndroid720pStrategy(int bitrate, int audioBitrate, int audioChannels) {
+ return new Android720pFormatStrategy(bitrate, audioBitrate, audioChannels);
+ }
+
+ /**
+ * Preset similar to iOS SDK's AVAssetExportPreset960x540.
+ * Note that encoding resolutions of this preset are not supported in all devices e.g. Nexus 4.
+ * On unsupported device encoded video stream will be broken without any exception.
+ */
+ public static MediaFormatStrategy createExportPreset960x540Strategy() {
+ return new ExportPreset960x540Strategy();
+ }
+
+ private MediaFormatStrategyPresets() {
+ }
+}
diff --git a/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/OutputFormatUnavailableException.java b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/OutputFormatUnavailableException.java
new file mode 100644
index 000000000..4fb9b33c9
--- /dev/null
+++ b/libs/android-transcoder/src/main/java/net/ypresto/androidtranscoder/format/OutputFormatUnavailableException.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Yuya Tanaka
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.ypresto.androidtranscoder.format;
+
+public class OutputFormatUnavailableException extends RuntimeException {
+ public OutputFormatUnavailableException(String detailMessage) {
+ super(detailMessage);
+ }
+}