diff --git a/api/current.txt b/api/current.txt index cb523cf99080c..0af3d80c96721 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11001,6 +11001,7 @@ package android.media { method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException; method public final void release(); method public final void releaseOutputBuffer(int, boolean); + method public final void setVideoScalingMode(int); method public final void start(); method public final void stop(); field public static int CONFIGURE_FLAG_ENCODE; @@ -11012,6 +11013,8 @@ package android.media { field public static final int INFO_TRY_AGAIN_LATER = -1; // 0xffffffff field public static final int MODE_AES_CTR = 1; // 0x1 field public static final int MODE_UNENCRYPTED = 0; // 0x0 + field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2 + field public static final int VIDEO_SCALING_MODE_STRETCH_TO_FIT = 1; // 0x1 } public static final class MediaCodec.BufferInfo { diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 258760f2ae961..ab8f88439964e 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -442,6 +442,19 @@ final public class MediaCodec { return getBuffers(false /* input */); } + /** The content is scaled to the surface dimensions */ + public static final int VIDEO_SCALING_MODE_STRETCH_TO_FIT = 1; + + /** The content is scaled, maintaining its aspect ratio, the whole + surface area is used, content may be cropped + */ + public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; + + /** If a surface has been specified in a previous call to {@link #configure} + specifies the scaling mode to use. The default is "stretch to fit". + */ + public native final void setVideoScalingMode(int mode); + private native final ByteBuffer[] getBuffers(boolean input); private static native final void native_init(); diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 8009fb5d73de1..f98c063b3b0ef 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -39,6 +39,8 @@ #include #include +#include + namespace android { // Keep these in sync with their equivalents in MediaCodec.java !!! @@ -111,9 +113,12 @@ status_t JMediaCodec::configure( int flags) { sp client; if (surfaceTexture != NULL) { - client = new SurfaceTextureClient(surfaceTexture); + mSurfaceTextureClient = new SurfaceTextureClient(surfaceTexture); + } else { + mSurfaceTextureClient.clear(); } - return mCodec->configure(format, client, crypto, flags); + + return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); } status_t JMediaCodec::start() { @@ -121,6 +126,8 @@ status_t JMediaCodec::start() { } status_t JMediaCodec::stop() { + mSurfaceTextureClient.clear(); + return mCodec->stop(); } @@ -227,6 +234,12 @@ status_t JMediaCodec::getBuffers( return OK; } +void JMediaCodec::setVideoScalingMode(int mode) { + if (mSurfaceTextureClient != NULL) { + native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); + } +} + } // namespace android //////////////////////////////////////////////////////////////////////////////// @@ -663,6 +676,24 @@ static jobjectArray android_media_MediaCodec_getBuffers( return NULL; } +static void android_media_MediaCodec_setVideoScalingMode( + JNIEnv *env, jobject thiz, jint mode) { + sp codec = getMediaCodec(env, thiz); + + if (codec == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return; + } + + if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW + && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { + jniThrowException(env, "java/lang/InvalidArgumentException", NULL); + return; + } + + codec->setVideoScalingMode(mode); +} + static void android_media_MediaCodec_native_init(JNIEnv *env) { jclass clazz = env->FindClass("android/media/MediaCodec"); CHECK(clazz != NULL); @@ -765,6 +796,9 @@ static JNINativeMethod gMethods[] = { { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", (void *)android_media_MediaCodec_getBuffers }, + { "setVideoScalingMode", "(I)V", + (void *)android_media_MediaCodec_setVideoScalingMode }, + { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, { "native_setup", "(Ljava/lang/String;ZZ)V", diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index e2688bec37467..4936b53b978ff 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -32,6 +32,7 @@ struct AString; struct ICrypto; struct ISurfaceTexture; struct MediaCodec; +struct SurfaceTextureClient; struct JMediaCodec : public RefBase { JMediaCodec( @@ -80,12 +81,15 @@ struct JMediaCodec : public RefBase { status_t getBuffers( JNIEnv *env, bool input, jobjectArray *bufArray) const; + void setVideoScalingMode(int mode); + protected: virtual ~JMediaCodec(); private: jclass mClass; jweak mObject; + sp mSurfaceTextureClient; sp mLooper; sp mCodec;