diff options
Diffstat (limited to 'android/media/effect')
36 files changed, 2132 insertions, 0 deletions
diff --git a/android/media/effect/Effect.java b/android/media/effect/Effect.java new file mode 100644 index 00000000..b2b44270 --- /dev/null +++ b/android/media/effect/Effect.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + + +/** + * <p>Effects are high-performance transformations that can be applied to image frames. These are + * passed in the form of OpenGL ES 2.0 texture names. Typical frames could be images loaded from + * disk, or frames from the camera or other video streams.</p> + * + * <p>To create an Effect you must first create an EffectContext. You can obtain an instance of the + * context's EffectFactory by calling + * {@link android.media.effect.EffectContext#getFactory() getFactory()}. The EffectFactory allows + * you to instantiate specific Effects.</p> + * + * <p>The application is responsible for creating an EGL context, and making it current before + * applying an effect. An effect is bound to a single EffectContext, which in turn is bound to a + * single EGL context. If your EGL context is destroyed, the EffectContext becomes invalid and any + * effects bound to this context can no longer be used.</p> + * + */ +public abstract class Effect { + + /** + * Get the effect name. + * + * Returns the unique name of the effect, which matches the name used for instantiating this + * effect by the EffectFactory. + * + * @return The name of the effect. + */ + public abstract String getName(); + + /** + * Apply an effect to GL textures. + * + * <p>Apply the Effect on the specified input GL texture, and write the result into the + * output GL texture. The texture names passed must be valid in the current GL context.</p> + * + * <p>The input texture must be a valid texture name with the given width and height and must be + * bound to a GL_TEXTURE_2D texture image (usually done by calling the glTexImage2D() function). + * Multiple mipmap levels may be provided.</p> + * + * <p>If the output texture has not been bound to a texture image, it will be automatically + * bound by the effect as a GL_TEXTURE_2D. It will contain one mipmap level (0), which will have + * the same size as the input. No other mipmap levels are defined. If the output texture was + * bound already, and its size does not match the input texture size, the result may be clipped + * or only partially fill the texture.</p> + * + * <p>Note, that regardless of whether a texture image was originally provided or not, both the + * input and output textures are owned by the caller. That is, the caller is responsible for + * calling glDeleteTextures() to deallocate the input and output textures.</p> + * + * @param inputTexId The GL texture name of a valid and bound input texture. + * @param width The width of the input texture in pixels. + * @param height The height of the input texture in pixels. + * @param outputTexId The GL texture name of the output texture. + */ + public abstract void apply(int inputTexId, int width, int height, int outputTexId); + + /** + * Set a filter parameter. + * + * Consult the effect documentation for a list of supported parameter keys for each effect. + * + * @param parameterKey The name of the parameter to adjust. + * @param value The new value to set the parameter to. + * @throws InvalidArgumentException if parameterName is not a recognized name, or the value is + * not a valid value for this parameter. + */ + public abstract void setParameter(String parameterKey, Object value); + + /** + * Set an effect listener. + * + * Some effects may report state changes back to the host, if a listener is set. Consult the + * individual effect documentation for more details. + * + * @param listener The listener to receive update callbacks on. + */ + public void setUpdateListener(EffectUpdateListener listener) { + } + + /** + * Release an effect. + * + * <p>Releases the effect and any resources associated with it. You may call this if you need to + * make sure acquired resources are no longer held by the effect. Releasing an effect makes it + * invalid for reuse.</p> + * + * <p>Note that this method must be called with the EffectContext and EGL context current, as + * the effect may release internal GL resources.</p> + */ + public abstract void release(); +} + diff --git a/android/media/effect/EffectContext.java b/android/media/effect/EffectContext.java new file mode 100644 index 00000000..a11b9c48 --- /dev/null +++ b/android/media/effect/EffectContext.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +import android.filterfw.core.CachedFrameManager; +import android.filterfw.core.FilterContext; +import android.filterfw.core.GLEnvironment; +import android.opengl.GLES20; + +/** + * <p>An EffectContext keeps all necessary state information to run Effects within a Open GL ES 2.0 + * context.</p> + * + * <p>Every EffectContext is bound to one GL context. The application is responsible for creating + * this EGL context, and making it current before applying any effect. If your EGL context is + * destroyed, the EffectContext becomes invalid and any effects bound to this context can no longer + * be used. If you switch to another EGL context, you must create a new EffectContext. Each Effect + * is bound to a single EffectContext, and can only be executed in that context.</p> + */ +public class EffectContext { + + private final int GL_STATE_FBO = 0; + private final int GL_STATE_PROGRAM = 1; + private final int GL_STATE_ARRAYBUFFER = 2; + private final int GL_STATE_COUNT = 3; + + FilterContext mFilterContext; + + private EffectFactory mFactory; + + private int[] mOldState = new int[GL_STATE_COUNT]; + + /** + * Creates a context within the current GL context. + * + * <p>Binds the EffectContext to the current OpenGL context. All subsequent calls to the + * EffectContext must be made in the GL context that was active during creation. + * When you have finished using a context, you must call {@link #release()}. to dispose of all + * resources associated with this context.</p> + */ + public static EffectContext createWithCurrentGlContext() { + EffectContext result = new EffectContext(); + result.initInCurrentGlContext(); + return result; + } + + /** + * Returns the EffectFactory for this context. + * + * <p>The EffectFactory returned from this method allows instantiating new effects within this + * context.</p> + * + * @return The EffectFactory instance for this context. + */ + public EffectFactory getFactory() { + return mFactory; + } + + /** + * Releases the context. + * + * <p>Releases all the resources and effects associated with the EffectContext. This renders the + * context and all the effects bound to this context invalid. You must no longer use the context + * or any of its bound effects after calling release().</p> + * + * <p>Note that this method must be called with the proper EGL context made current, as the + * EffectContext and its effects may release internal GL resources.</p> + */ + public void release() { + mFilterContext.tearDown(); + mFilterContext = null; + } + + private EffectContext() { + mFilterContext = new FilterContext(); + mFilterContext.setFrameManager(new CachedFrameManager()); + mFactory = new EffectFactory(this); + } + + private void initInCurrentGlContext() { + if (!GLEnvironment.isAnyContextActive()) { + throw new RuntimeException("Attempting to initialize EffectContext with no active " + + "GL context!"); + } + GLEnvironment glEnvironment = new GLEnvironment(); + glEnvironment.initWithCurrentContext(); + mFilterContext.initGLEnvironment(glEnvironment); + } + + final void assertValidGLState() { + GLEnvironment glEnv = mFilterContext.getGLEnvironment(); + if (glEnv == null || !glEnv.isContextActive()) { + if (GLEnvironment.isAnyContextActive()) { + throw new RuntimeException("Applying effect in wrong GL context!"); + } else { + throw new RuntimeException("Attempting to apply effect without valid GL context!"); + } + } + } + + final void saveGLState() { + GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, mOldState, GL_STATE_FBO); + GLES20.glGetIntegerv(GLES20.GL_CURRENT_PROGRAM, mOldState, GL_STATE_PROGRAM); + GLES20.glGetIntegerv(GLES20.GL_ARRAY_BUFFER_BINDING, mOldState, GL_STATE_ARRAYBUFFER); + } + + final void restoreGLState() { + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mOldState[GL_STATE_FBO]); + GLES20.glUseProgram(mOldState[GL_STATE_PROGRAM]); + GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mOldState[GL_STATE_ARRAYBUFFER]); + } +} + diff --git a/android/media/effect/EffectFactory.java b/android/media/effect/EffectFactory.java new file mode 100644 index 00000000..f6fcba71 --- /dev/null +++ b/android/media/effect/EffectFactory.java @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +import java.lang.reflect.Constructor; + +/** + * <p>The EffectFactory class defines the list of available Effects, and provides functionality to + * inspect and instantiate them. Some effects may not be available on all platforms, so before + * creating a certain effect, the application should confirm that the effect is supported on this + * platform by calling {@link #isEffectSupported(String)}.</p> + */ +public class EffectFactory { + + private EffectContext mEffectContext; + + private final static String[] EFFECT_PACKAGES = { + "android.media.effect.effects.", // Default effect package + "" // Allows specifying full class path + }; + + /** List of Effects */ + /** + * <p>Copies the input texture to the output.</p> + * <p>Available parameters: None</p> + * @hide + */ + public final static String EFFECT_IDENTITY = "IdentityEffect"; + + /** + * <p>Adjusts the brightness of the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>brightness</code></td> + * <td>The brightness multiplier.</td> + * <td>Positive float. 1.0 means no change; + larger values will increase brightness.</td> + * </tr> + * </table> + */ + public final static String EFFECT_BRIGHTNESS = + "android.media.effect.effects.BrightnessEffect"; + + /** + * <p>Adjusts the contrast of the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>contrast</code></td> + * <td>The contrast multiplier.</td> + * <td>Float. 1.0 means no change; + larger values will increase contrast.</td> + * </tr> + * </table> + */ + public final static String EFFECT_CONTRAST = + "android.media.effect.effects.ContrastEffect"; + + /** + * <p>Applies a fisheye lens distortion to the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>scale</code></td> + * <td>The scale of the distortion.</td> + * <td>Float, between 0 and 1. Zero means no distortion.</td> + * </tr> + * </table> + */ + public final static String EFFECT_FISHEYE = + "android.media.effect.effects.FisheyeEffect"; + + /** + * <p>Replaces the background of the input frames with frames from a + * selected video. Requires an initial learning period with only the + * background visible before the effect becomes active. The effect will wait + * until it does not see any motion in the scene before learning the + * background and starting the effect.</p> + * + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>source</code></td> + * <td>A URI for the background video to use. This parameter must be + * supplied before calling apply() for the first time.</td> + * <td>String, such as from + * {@link android.net.Uri#toString Uri.toString()}</td> + * </tr> + * </table> + * + * <p>If the update listener is set for this effect using + * {@link Effect#setUpdateListener}, it will be called when the effect has + * finished learning the background, with a null value for the info + * parameter.</p> + */ + public final static String EFFECT_BACKDROPPER = + "android.media.effect.effects.BackDropperEffect"; + + /** + * <p>Attempts to auto-fix the image based on histogram equalization.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>scale</code></td> + * <td>The scale of the adjustment.</td> + * <td>Float, between 0 and 1. Zero means no adjustment, while 1 indicates the maximum + * amount of adjustment.</td> + * </tr> + * </table> + */ + public final static String EFFECT_AUTOFIX = + "android.media.effect.effects.AutoFixEffect"; + + /** + * <p>Adjusts the range of minimal and maximal color pixel intensities.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>black</code></td> + * <td>The value of the minimal pixel.</td> + * <td>Float, between 0 and 1.</td> + * </tr> + * <tr><td><code>white</code></td> + * <td>The value of the maximal pixel.</td> + * <td>Float, between 0 and 1.</td> + * </tr> + * </table> + */ + public final static String EFFECT_BLACKWHITE = + "android.media.effect.effects.BlackWhiteEffect"; + + /** + * <p>Crops an upright rectangular area from the image. If the crop region falls outside of + * the image bounds, the results are undefined.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>xorigin</code></td> + * <td>The origin's x-value.</td> + * <td>Integer, between 0 and width of the image.</td> + * </tr> + * <tr><td><code>yorigin</code></td> + * <td>The origin's y-value.</td> + * <td>Integer, between 0 and height of the image.</td> + * </tr> + * <tr><td><code>width</code></td> + * <td>The width of the cropped image.</td> + * <td>Integer, between 1 and the width of the image minus xorigin.</td> + * </tr> + * <tr><td><code>height</code></td> + * <td>The height of the cropped image.</td> + * <td>Integer, between 1 and the height of the image minus yorigin.</td> + * </tr> + * </table> + */ + public final static String EFFECT_CROP = + "android.media.effect.effects.CropEffect"; + + /** + * <p>Applies a cross process effect on image, in which the red and green channels are + * enhanced while the blue channel is restricted.</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_CROSSPROCESS = + "android.media.effect.effects.CrossProcessEffect"; + + /** + * <p>Applies black and white documentary style effect on image..</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_DOCUMENTARY = + "android.media.effect.effects.DocumentaryEffect"; + + + /** + * <p>Overlays a bitmap (with premultiplied alpha channel) onto the input image. The bitmap + * is stretched to fit the input image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>bitmap</code></td> + * <td>The overlay bitmap.</td> + * <td>A non-null Bitmap instance.</td> + * </tr> + * </table> + */ + public final static String EFFECT_BITMAPOVERLAY = + "android.media.effect.effects.BitmapOverlayEffect"; + + /** + * <p>Representation of photo using only two color tones.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>first_color</code></td> + * <td>The first color tone.</td> + * <td>Integer, representing an ARGB color with 8 bits per channel. May be created using + * {@link android.graphics.Color Color} class.</td> + * </tr> + * <tr><td><code>second_color</code></td> + * <td>The second color tone.</td> + * <td>Integer, representing an ARGB color with 8 bits per channel. May be created using + * {@link android.graphics.Color Color} class.</td> + * </tr> + * </table> + */ + public final static String EFFECT_DUOTONE = + "android.media.effect.effects.DuotoneEffect"; + + /** + * <p>Applies back-light filling to the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>strength</code></td> + * <td>The strength of the backlight.</td> + * <td>Float, between 0 and 1. Zero means no change.</td> + * </tr> + * </table> + */ + public final static String EFFECT_FILLLIGHT = + "android.media.effect.effects.FillLightEffect"; + + /** + * <p>Flips image vertically and/or horizontally.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>vertical</code></td> + * <td>Whether to flip image vertically.</td> + * <td>Boolean</td> + * </tr> + * <tr><td><code>horizontal</code></td> + * <td>Whether to flip image horizontally.</td> + * <td>Boolean</td> + * </tr> + * </table> + */ + public final static String EFFECT_FLIP = + "android.media.effect.effects.FlipEffect"; + + /** + * <p>Applies film grain effect to image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>strength</code></td> + * <td>The strength of the grain effect.</td> + * <td>Float, between 0 and 1. Zero means no change.</td> + * </tr> + * </table> + */ + public final static String EFFECT_GRAIN = + "android.media.effect.effects.GrainEffect"; + + /** + * <p>Converts image to grayscale.</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_GRAYSCALE = + "android.media.effect.effects.GrayscaleEffect"; + + /** + * <p>Applies lomo-camera style effect to image.</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_LOMOISH = + "android.media.effect.effects.LomoishEffect"; + + /** + * <p>Inverts the image colors.</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_NEGATIVE = + "android.media.effect.effects.NegativeEffect"; + + /** + * <p>Applies posterization effect to image.</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_POSTERIZE = + "android.media.effect.effects.PosterizeEffect"; + + /** + * <p>Removes red eyes on specified region.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>centers</code></td> + * <td>Multiple center points (x, y) of the red eye regions.</td> + * <td>An array of floats, where (f[2*i], f[2*i+1]) specifies the center of the i'th eye. + * Coordinate values are expected to be normalized between 0 and 1.</td> + * </tr> + * </table> + */ + public final static String EFFECT_REDEYE = + "android.media.effect.effects.RedEyeEffect"; + + /** + * <p>Rotates the image. The output frame size must be able to fit the rotated version of + * the input image. Note that the rotation snaps to a the closest multiple of 90 degrees.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>angle</code></td> + * <td>The angle of rotation in degrees.</td> + * <td>Integer value. This will be rounded to the nearest multiple of 90.</td> + * </tr> + * </table> + */ + public final static String EFFECT_ROTATE = + "android.media.effect.effects.RotateEffect"; + + /** + * <p>Adjusts color saturation of image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>scale</code></td> + * <td>The scale of color saturation.</td> + * <td>Float, between -1 and 1. 0 means no change, while -1 indicates full desaturation, + * i.e. grayscale.</td> + * </tr> + * </table> + */ + public final static String EFFECT_SATURATE = + "android.media.effect.effects.SaturateEffect"; + + /** + * <p>Converts image to sepia tone.</p> + * <p>Available parameters: None</p> + */ + public final static String EFFECT_SEPIA = + "android.media.effect.effects.SepiaEffect"; + + /** + * <p>Sharpens the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>scale</code></td> + * <td>The degree of sharpening.</td> + * <td>Float, between 0 and 1. 0 means no change.</td> + * </tr> + * </table> + */ + public final static String EFFECT_SHARPEN = + "android.media.effect.effects.SharpenEffect"; + + /** + * <p>Rotates the image according to the specified angle, and crops the image so that no + * non-image portions are visible.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>angle</code></td> + * <td>The angle of rotation.</td> + * <td>Float, between -45 and +45.</td> + * </tr> + * </table> + */ + public final static String EFFECT_STRAIGHTEN = + "android.media.effect.effects.StraightenEffect"; + + /** + * <p>Adjusts color temperature of the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>scale</code></td> + * <td>The value of color temperature.</td> + * <td>Float, between 0 and 1, with 0 indicating cool, and 1 indicating warm. A value of + * of 0.5 indicates no change.</td> + * </tr> + * </table> + */ + public final static String EFFECT_TEMPERATURE = + "android.media.effect.effects.ColorTemperatureEffect"; + + /** + * <p>Tints the photo with specified color.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>tint</code></td> + * <td>The color of the tint.</td> + * <td>Integer, representing an ARGB color with 8 bits per channel. May be created using + * {@link android.graphics.Color Color} class.</td> + * </tr> + * </table> + */ + public final static String EFFECT_TINT = + "android.media.effect.effects.TintEffect"; + + /** + * <p>Adds a vignette effect to image, i.e. fades away the outer image edges.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * <tr><td><code>scale</code></td> + * <td>The scale of vignetting.</td> + * <td>Float, between 0 and 1. 0 means no change.</td> + * </tr> + * </table> + */ + public final static String EFFECT_VIGNETTE = + "android.media.effect.effects.VignetteEffect"; + + EffectFactory(EffectContext effectContext) { + mEffectContext = effectContext; + } + + /** + * Instantiate a new effect with the given effect name. + * + * <p>The effect's parameters will be set to their default values.</p> + * + * <p>Note that the EGL context associated with the current EffectContext need not be made + * current when creating an effect. This allows the host application to instantiate effects + * before any EGL context has become current.</p> + * + * @param effectName The name of the effect to create. + * @return A new Effect instance. + * @throws IllegalArgumentException if the effect with the specified name is not supported or + * not known. + */ + public Effect createEffect(String effectName) { + Class effectClass = getEffectClassByName(effectName); + if (effectClass == null) { + throw new IllegalArgumentException("Cannot instantiate unknown effect '" + + effectName + "'!"); + } + return instantiateEffect(effectClass, effectName); + } + + /** + * Check if an effect is supported on this platform. + * + * <p>Some effects may only be available on certain platforms. Use this method before + * instantiating an effect to make sure it is supported.</p> + * + * @param effectName The name of the effect. + * @return true, if the effect is supported on this platform. + * @throws IllegalArgumentException if the effect name is not known. + */ + public static boolean isEffectSupported(String effectName) { + return getEffectClassByName(effectName) != null; + } + + private static Class getEffectClassByName(String className) { + Class effectClass = null; + + // Get context's classloader; otherwise cannot load non-framework effects + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + + // Look for the class in the imported packages + for (String packageName : EFFECT_PACKAGES) { + try { + effectClass = contextClassLoader.loadClass(packageName + className); + } catch (ClassNotFoundException e) { + continue; + } + // Exit loop if class was found. + if (effectClass != null) { + break; + } + } + return effectClass; + } + + private Effect instantiateEffect(Class effectClass, String name) { + // Make sure this is an Effect subclass + try { + effectClass.asSubclass(Effect.class); + } catch (ClassCastException e) { + throw new IllegalArgumentException("Attempting to allocate effect '" + effectClass + + "' which is not a subclass of Effect!", e); + } + + // Look for the correct constructor + Constructor effectConstructor = null; + try { + effectConstructor = effectClass.getConstructor(EffectContext.class, String.class); + } catch (NoSuchMethodException e) { + throw new RuntimeException("The effect class '" + effectClass + "' does not have " + + "the required constructor.", e); + } + + // Construct the effect + Effect effect = null; + try { + effect = (Effect)effectConstructor.newInstance(mEffectContext, name); + } catch (Throwable t) { + throw new RuntimeException("There was an error constructing the effect '" + effectClass + + "'!", t); + } + + return effect; + } +} diff --git a/android/media/effect/EffectUpdateListener.java b/android/media/effect/EffectUpdateListener.java new file mode 100644 index 00000000..155fe49d --- /dev/null +++ b/android/media/effect/EffectUpdateListener.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +/** + * Some effects may issue callbacks to inform the host of changes to the effect state. This is the + * listener interface for receiving those callbacks. + */ +public interface EffectUpdateListener { + + /** + * Called when the effect state is updated. + * + * @param effect The effect that has been updated. + * @param info A value that gives more information about the update. See the effect's + * documentation for more details on what this object is. + */ + public void onEffectUpdated(Effect effect, Object info); + +} + diff --git a/android/media/effect/FilterEffect.java b/android/media/effect/FilterEffect.java new file mode 100644 index 00000000..34b35496 --- /dev/null +++ b/android/media/effect/FilterEffect.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +import android.filterfw.core.FilterContext; +import android.filterfw.core.GLFrame; +import android.filterfw.core.Frame; +import android.filterfw.core.FrameFormat; +import android.filterfw.core.FrameManager; +import android.filterfw.format.ImageFormat; + +/** + * The FilterEffect class is the base class for all Effects based on Filters from the Mobile + * Filter Framework (MFF). + * @hide + */ +public abstract class FilterEffect extends Effect { + + protected EffectContext mEffectContext; + private String mName; + + /** + * Protected constructor as FilterEffects should be created by Factory. + */ + protected FilterEffect(EffectContext context, String name) { + mEffectContext = context; + mName = name; + } + + /** + * Get the effect name. + * + * Returns the unique name of the effect, which matches the name used for instantiating this + * effect by the EffectFactory. + * + * @return The name of the effect. + */ + @Override + public String getName() { + return mName; + } + + // Helper Methods for subclasses /////////////////////////////////////////////////////////////// + /** + * Call this before manipulating the GL context. Will assert that the GL environment is in a + * valid state, and save it. + */ + protected void beginGLEffect() { + mEffectContext.assertValidGLState(); + mEffectContext.saveGLState(); + } + + /** + * Call this after manipulating the GL context. Restores the previous GL state. + */ + protected void endGLEffect() { + mEffectContext.restoreGLState(); + } + + /** + * Returns the active filter context for this effect. + */ + protected FilterContext getFilterContext() { + return mEffectContext.mFilterContext; + } + + /** + * Converts a texture into a Frame. + */ + protected Frame frameFromTexture(int texId, int width, int height) { + FrameManager manager = getFilterContext().getFrameManager(); + FrameFormat format = ImageFormat.create(width, height, + ImageFormat.COLORSPACE_RGBA, + FrameFormat.TARGET_GPU); + Frame frame = manager.newBoundFrame(format, + GLFrame.EXISTING_TEXTURE_BINDING, + texId); + frame.setTimestamp(Frame.TIMESTAMP_UNKNOWN); + return frame; + } + +} + diff --git a/android/media/effect/FilterGraphEffect.java b/android/media/effect/FilterGraphEffect.java new file mode 100644 index 00000000..80c695bd --- /dev/null +++ b/android/media/effect/FilterGraphEffect.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +import android.filterfw.core.Filter; +import android.filterfw.core.FilterGraph; +import android.filterfw.core.GraphRunner; +import android.filterfw.core.SyncRunner; +import android.media.effect.FilterEffect; +import android.media.effect.EffectContext; +import android.filterfw.io.GraphIOException; +import android.filterfw.io.GraphReader; +import android.filterfw.io.TextGraphReader; + +/** + * Effect subclass for effects based on a single Filter. Subclasses need only invoke the + * constructor with the correct arguments to obtain an Effect implementation. + * + * @hide + */ +public class FilterGraphEffect extends FilterEffect { + + private static final String TAG = "FilterGraphEffect"; + + protected String mInputName; + protected String mOutputName; + protected GraphRunner mRunner; + protected FilterGraph mGraph; + protected Class mSchedulerClass; + + /** + * Constructs a new FilterGraphEffect. + * + * @param name The name of this effect (used to create it in the EffectFactory). + * @param graphString The graph string to create the graph. + * @param inputName The name of the input GLTextureSource filter. + * @param outputName The name of the output GLTextureSource filter. + */ + public FilterGraphEffect(EffectContext context, + String name, + String graphString, + String inputName, + String outputName, + Class scheduler) { + super(context, name); + + mInputName = inputName; + mOutputName = outputName; + mSchedulerClass = scheduler; + createGraph(graphString); + + } + + private void createGraph(String graphString) { + GraphReader reader = new TextGraphReader(); + try { + mGraph = reader.readGraphString(graphString); + } catch (GraphIOException e) { + throw new RuntimeException("Could not setup effect", e); + } + + if (mGraph == null) { + throw new RuntimeException("Could not setup effect"); + } + mRunner = new SyncRunner(getFilterContext(), mGraph, mSchedulerClass); + } + + @Override + public void apply(int inputTexId, int width, int height, int outputTexId) { + beginGLEffect(); + Filter src = mGraph.getFilter(mInputName); + if (src != null) { + src.setInputValue("texId", inputTexId); + src.setInputValue("width", width); + src.setInputValue("height", height); + } else { + throw new RuntimeException("Internal error applying effect"); + } + Filter dest = mGraph.getFilter(mOutputName); + if (dest != null) { + dest.setInputValue("texId", outputTexId); + } else { + throw new RuntimeException("Internal error applying effect"); + } + try { + mRunner.run(); + } catch (RuntimeException e) { + throw new RuntimeException("Internal error applying effect: ", e); + } + endGLEffect(); + } + + @Override + public void setParameter(String parameterKey, Object value) { + } + + @Override + public void release() { + mGraph.tearDown(getFilterContext()); + mGraph = null; + } +} diff --git a/android/media/effect/SingleFilterEffect.java b/android/media/effect/SingleFilterEffect.java new file mode 100644 index 00000000..47900dfc --- /dev/null +++ b/android/media/effect/SingleFilterEffect.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +import android.filterfw.core.Filter; +import android.filterfw.core.FilterFactory; +import android.filterfw.core.FilterFunction; +import android.filterfw.core.Frame; +import android.media.effect.EffectContext; + +/** + * Effect subclass for effects based on a single Filter. Subclasses need only invoke the + * constructor with the correct arguments to obtain an Effect implementation. + * + * @hide + */ +public class SingleFilterEffect extends FilterEffect { + + protected FilterFunction mFunction; + protected String mInputName; + protected String mOutputName; + + /** + * Constructs a new FilterFunctionEffect. + * + * @param name The name of this effect (used to create it in the EffectFactory). + * @param filterClass The class of the filter to wrap. + * @param inputName The name of the input image port. + * @param outputName The name of the output image port. + * @param finalParameters Key-value pairs of final input port assignments. + */ + public SingleFilterEffect(EffectContext context, + String name, + Class filterClass, + String inputName, + String outputName, + Object... finalParameters) { + super(context, name); + + mInputName = inputName; + mOutputName = outputName; + + String filterName = filterClass.getSimpleName(); + FilterFactory factory = FilterFactory.sharedFactory(); + Filter filter = factory.createFilterByClass(filterClass, filterName); + filter.initWithAssignmentList(finalParameters); + + mFunction = new FilterFunction(getFilterContext(), filter); + } + + @Override + public void apply(int inputTexId, int width, int height, int outputTexId) { + beginGLEffect(); + + Frame inputFrame = frameFromTexture(inputTexId, width, height); + Frame outputFrame = frameFromTexture(outputTexId, width, height); + + Frame resultFrame = mFunction.executeWithArgList(mInputName, inputFrame); + + outputFrame.setDataFromFrame(resultFrame); + + inputFrame.release(); + outputFrame.release(); + resultFrame.release(); + + endGLEffect(); + } + + @Override + public void setParameter(String parameterKey, Object value) { + mFunction.setInputValue(parameterKey, value); + } + + @Override + public void release() { + mFunction.tearDown(); + mFunction = null; + } +} + diff --git a/android/media/effect/SizeChangeEffect.java b/android/media/effect/SizeChangeEffect.java new file mode 100644 index 00000000..1bf7d400 --- /dev/null +++ b/android/media/effect/SizeChangeEffect.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect; + +import android.filterfw.core.Frame; +import android.media.effect.EffectContext; + +/** + * Effect subclass for effects based on a single Filter with output size differnet + * from input. Subclasses need only invoke the constructor with the correct arguments + * to obtain an Effect implementation. + * + * @hide + */ +public class SizeChangeEffect extends SingleFilterEffect { + + public SizeChangeEffect(EffectContext context, + String name, + Class filterClass, + String inputName, + String outputName, + Object... finalParameters) { + super(context, name, filterClass, inputName, outputName, finalParameters); + } + + @Override + public void apply(int inputTexId, int width, int height, int outputTexId) { + beginGLEffect(); + + Frame inputFrame = frameFromTexture(inputTexId, width, height); + Frame resultFrame = mFunction.executeWithArgList(mInputName, inputFrame); + + int outputWidth = resultFrame.getFormat().getWidth(); + int outputHeight = resultFrame.getFormat().getHeight(); + + Frame outputFrame = frameFromTexture(outputTexId, outputWidth, outputHeight); + outputFrame.setDataFromFrame(resultFrame); + + inputFrame.release(); + outputFrame.release(); + resultFrame.release(); + + endGLEffect(); + } +} diff --git a/android/media/effect/effects/AutoFixEffect.java b/android/media/effect/effects/AutoFixEffect.java new file mode 100644 index 00000000..44a141b6 --- /dev/null +++ b/android/media/effect/effects/AutoFixEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.AutoFixFilter; + +/** + * @hide + */ +public class AutoFixEffect extends SingleFilterEffect { + public AutoFixEffect(EffectContext context, String name) { + super(context, name, AutoFixFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/BackDropperEffect.java b/android/media/effect/effects/BackDropperEffect.java new file mode 100644 index 00000000..f977e600 --- /dev/null +++ b/android/media/effect/effects/BackDropperEffect.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.filterfw.core.Filter; +import android.filterfw.core.OneShotScheduler; +import android.media.effect.EffectContext; +import android.media.effect.FilterGraphEffect; +import android.media.effect.EffectUpdateListener; + +import android.filterpacks.videoproc.BackDropperFilter; +import android.filterpacks.videoproc.BackDropperFilter.LearningDoneListener; + +/** + * Background replacement Effect. + * + * Replaces the background of the input video stream with a selected video + * Learns the background when it first starts up; + * needs unobstructed view of background when this happens. + * + * Effect parameters: + * source: A URI for the background video + * Listener: Called when learning period is complete + * + * @hide + */ +public class BackDropperEffect extends FilterGraphEffect { + private static final String mGraphDefinition = + "@import android.filterpacks.base;\n" + + "@import android.filterpacks.videoproc;\n" + + "@import android.filterpacks.videosrc;\n" + + "\n" + + "@filter GLTextureSource foreground {\n" + + " texId = 0;\n" + // Will be set by base class + " width = 0;\n" + + " height = 0;\n" + + " repeatFrame = true;\n" + + "}\n" + + "\n" + + "@filter MediaSource background {\n" + + " sourceUrl = \"no_file_specified\";\n" + + " waitForNewFrame = false;\n" + + " sourceIsUrl = true;\n" + + "}\n" + + "\n" + + "@filter BackDropperFilter replacer {\n" + + " autowbToggle = 1;\n" + + "}\n" + + "\n" + + "@filter GLTextureTarget output {\n" + + " texId = 0;\n" + + "}\n" + + "\n" + + "@connect foreground[frame] => replacer[video];\n" + + "@connect background[video] => replacer[background];\n" + + "@connect replacer[video] => output[frame];\n"; + + private EffectUpdateListener mEffectListener = null; + + private LearningDoneListener mLearningListener = new LearningDoneListener() { + public void onLearningDone(BackDropperFilter filter) { + if (mEffectListener != null) { + mEffectListener.onEffectUpdated(BackDropperEffect.this, null); + } + } + }; + + public BackDropperEffect(EffectContext context, String name) { + super(context, name, mGraphDefinition, "foreground", "output", OneShotScheduler.class); + + Filter replacer = mGraph.getFilter("replacer"); + replacer.setInputValue("learningDoneListener", mLearningListener); + } + + @Override + public void setParameter(String parameterKey, Object value) { + if (parameterKey.equals("source")) { + Filter background = mGraph.getFilter("background"); + background.setInputValue("sourceUrl", value); + } else if (parameterKey.equals("context")) { + Filter background = mGraph.getFilter("background"); + background.setInputValue("context", value); + } + } + + @Override + public void setUpdateListener(EffectUpdateListener listener) { + mEffectListener = listener; + } + +}
\ No newline at end of file diff --git a/android/media/effect/effects/BitmapOverlayEffect.java b/android/media/effect/effects/BitmapOverlayEffect.java new file mode 100644 index 00000000..43f461c8 --- /dev/null +++ b/android/media/effect/effects/BitmapOverlayEffect.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.BitmapOverlayFilter; + +/** + * @hide + */ +public class BitmapOverlayEffect extends SingleFilterEffect { + public BitmapOverlayEffect(EffectContext context, String name) { + super(context, name, BitmapOverlayFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/BlackWhiteEffect.java b/android/media/effect/effects/BlackWhiteEffect.java new file mode 100644 index 00000000..771afff8 --- /dev/null +++ b/android/media/effect/effects/BlackWhiteEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.BlackWhiteFilter; + +/** + * @hide + */ +public class BlackWhiteEffect extends SingleFilterEffect { + public BlackWhiteEffect(EffectContext context, String name) { + super(context, name, BlackWhiteFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/BrightnessEffect.java b/android/media/effect/effects/BrightnessEffect.java new file mode 100644 index 00000000..774e72f7 --- /dev/null +++ b/android/media/effect/effects/BrightnessEffect.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.BrightnessFilter; + +/** + * @hide + */ +public class BrightnessEffect extends SingleFilterEffect { + public BrightnessEffect(EffectContext context, String name) { + super(context, name, BrightnessFilter.class, "image", "image"); + } +} + diff --git a/android/media/effect/effects/ColorTemperatureEffect.java b/android/media/effect/effects/ColorTemperatureEffect.java new file mode 100644 index 00000000..62d98ced --- /dev/null +++ b/android/media/effect/effects/ColorTemperatureEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.ColorTemperatureFilter; + +/** + * @hide + */ +public class ColorTemperatureEffect extends SingleFilterEffect { + public ColorTemperatureEffect(EffectContext context, String name) { + super(context, name, ColorTemperatureFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/ContrastEffect.java b/android/media/effect/effects/ContrastEffect.java new file mode 100644 index 00000000..d5bfc21f --- /dev/null +++ b/android/media/effect/effects/ContrastEffect.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.ContrastFilter; + +/** + * @hide + */ +public class ContrastEffect extends SingleFilterEffect { + public ContrastEffect(EffectContext context, String name) { + super(context, name, ContrastFilter.class, "image", "image"); + } +} + diff --git a/android/media/effect/effects/CropEffect.java b/android/media/effect/effects/CropEffect.java new file mode 100644 index 00000000..7e1c495a --- /dev/null +++ b/android/media/effect/effects/CropEffect.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SizeChangeEffect; +import android.filterpacks.imageproc.CropRectFilter; + +/** + * @hide + */ +//public class CropEffect extends SingleFilterEffect { +public class CropEffect extends SizeChangeEffect { + public CropEffect(EffectContext context, String name) { + super(context, name, CropRectFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/CrossProcessEffect.java b/android/media/effect/effects/CrossProcessEffect.java new file mode 100644 index 00000000..d7a7df58 --- /dev/null +++ b/android/media/effect/effects/CrossProcessEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.CrossProcessFilter; + +/** + * @hide + */ +public class CrossProcessEffect extends SingleFilterEffect { + public CrossProcessEffect(EffectContext context, String name) { + super(context, name, CrossProcessFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/DocumentaryEffect.java b/android/media/effect/effects/DocumentaryEffect.java new file mode 100644 index 00000000..1a5ea351 --- /dev/null +++ b/android/media/effect/effects/DocumentaryEffect.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.DocumentaryFilter; + +/** + * @hide + */ +public class DocumentaryEffect extends SingleFilterEffect { + public DocumentaryEffect(EffectContext context, String name) { + super(context, name, DocumentaryFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/DuotoneEffect.java b/android/media/effect/effects/DuotoneEffect.java new file mode 100644 index 00000000..1391b1f2 --- /dev/null +++ b/android/media/effect/effects/DuotoneEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.DuotoneFilter; + +/** + * @hide + */ +public class DuotoneEffect extends SingleFilterEffect { + public DuotoneEffect(EffectContext context, String name) { + super(context, name, DuotoneFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/FillLightEffect.java b/android/media/effect/effects/FillLightEffect.java new file mode 100644 index 00000000..5260de34 --- /dev/null +++ b/android/media/effect/effects/FillLightEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.FillLightFilter; + +/** + * @hide + */ +public class FillLightEffect extends SingleFilterEffect { + public FillLightEffect(EffectContext context, String name) { + super(context, name, FillLightFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/FisheyeEffect.java b/android/media/effect/effects/FisheyeEffect.java new file mode 100644 index 00000000..6abfe420 --- /dev/null +++ b/android/media/effect/effects/FisheyeEffect.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.FisheyeFilter; + +/** + * @hide + */ +public class FisheyeEffect extends SingleFilterEffect { + public FisheyeEffect(EffectContext context, String name) { + super(context, name, FisheyeFilter.class, "image", "image"); + } +} + diff --git a/android/media/effect/effects/FlipEffect.java b/android/media/effect/effects/FlipEffect.java new file mode 100644 index 00000000..0f5c4212 --- /dev/null +++ b/android/media/effect/effects/FlipEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.FlipFilter; + +/** + * @hide + */ +public class FlipEffect extends SingleFilterEffect { + public FlipEffect(EffectContext context, String name) { + super(context, name, FlipFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/GrainEffect.java b/android/media/effect/effects/GrainEffect.java new file mode 100644 index 00000000..2fda7e90 --- /dev/null +++ b/android/media/effect/effects/GrainEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.GrainFilter; + +/** + * @hide + */ +public class GrainEffect extends SingleFilterEffect { + public GrainEffect(EffectContext context, String name) { + super(context, name, GrainFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/GrayscaleEffect.java b/android/media/effect/effects/GrayscaleEffect.java new file mode 100644 index 00000000..26ca081f --- /dev/null +++ b/android/media/effect/effects/GrayscaleEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.ToGrayFilter; + +/** + * @hide + */ +public class GrayscaleEffect extends SingleFilterEffect { + public GrayscaleEffect(EffectContext context, String name) { + super(context, name, ToGrayFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/IdentityEffect.java b/android/media/effect/effects/IdentityEffect.java new file mode 100644 index 00000000..d07779ee --- /dev/null +++ b/android/media/effect/effects/IdentityEffect.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.filterfw.core.Frame; +import android.media.effect.EffectContext; +import android.media.effect.FilterEffect; + +/** + * @hide + */ +public class IdentityEffect extends FilterEffect { + + public IdentityEffect(EffectContext context, String name) { + super(context, name); + } + + @Override + public void apply(int inputTexId, int width, int height, int outputTexId) { + beginGLEffect(); + + Frame inputFrame = frameFromTexture(inputTexId, width, height); + Frame outputFrame = frameFromTexture(outputTexId, width, height); + + outputFrame.setDataFromFrame(inputFrame); + + inputFrame.release(); + outputFrame.release(); + + endGLEffect(); + } + + @Override + public void setParameter(String parameterKey, Object value) { + throw new IllegalArgumentException("Unknown parameter " + parameterKey + + " for IdentityEffect!"); + } + + @Override + public void release() { + } +} + diff --git a/android/media/effect/effects/LomoishEffect.java b/android/media/effect/effects/LomoishEffect.java new file mode 100644 index 00000000..776e53c5 --- /dev/null +++ b/android/media/effect/effects/LomoishEffect.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.LomoishFilter; + +/** + * @hide + */ +public class LomoishEffect extends SingleFilterEffect { + public LomoishEffect(EffectContext context, String name) { + super(context, name, LomoishFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/NegativeEffect.java b/android/media/effect/effects/NegativeEffect.java new file mode 100644 index 00000000..29fc94a1 --- /dev/null +++ b/android/media/effect/effects/NegativeEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.NegativeFilter; + +/** + * @hide + */ +public class NegativeEffect extends SingleFilterEffect { + public NegativeEffect(EffectContext context, String name) { + super(context, name, NegativeFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/PosterizeEffect.java b/android/media/effect/effects/PosterizeEffect.java new file mode 100644 index 00000000..20a8a37b --- /dev/null +++ b/android/media/effect/effects/PosterizeEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.PosterizeFilter; + +/** + * @hide + */ +public class PosterizeEffect extends SingleFilterEffect { + public PosterizeEffect(EffectContext context, String name) { + super(context, name, PosterizeFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/RedEyeEffect.java b/android/media/effect/effects/RedEyeEffect.java new file mode 100644 index 00000000..8ed9909c --- /dev/null +++ b/android/media/effect/effects/RedEyeEffect.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.RedEyeFilter; + +/** + * @hide + */ +public class RedEyeEffect extends SingleFilterEffect { + public RedEyeEffect(EffectContext context, String name) { + super(context, name, RedEyeFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/RotateEffect.java b/android/media/effect/effects/RotateEffect.java new file mode 100644 index 00000000..23400152 --- /dev/null +++ b/android/media/effect/effects/RotateEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SizeChangeEffect; +import android.filterpacks.imageproc.RotateFilter; + +/** + * @hide + */ +public class RotateEffect extends SizeChangeEffect { + public RotateEffect(EffectContext context, String name) { + super(context, name, RotateFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/SaturateEffect.java b/android/media/effect/effects/SaturateEffect.java new file mode 100644 index 00000000..fe9250a7 --- /dev/null +++ b/android/media/effect/effects/SaturateEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.SaturateFilter; + +/** + * @hide + */ +public class SaturateEffect extends SingleFilterEffect { + public SaturateEffect(EffectContext context, String name) { + super(context, name, SaturateFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/SepiaEffect.java b/android/media/effect/effects/SepiaEffect.java new file mode 100644 index 00000000..de85b2d4 --- /dev/null +++ b/android/media/effect/effects/SepiaEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.SepiaFilter; + +/** + * @hide + */ +public class SepiaEffect extends SingleFilterEffect { + public SepiaEffect(EffectContext context, String name) { + super(context, name, SepiaFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/SharpenEffect.java b/android/media/effect/effects/SharpenEffect.java new file mode 100644 index 00000000..46776ebf --- /dev/null +++ b/android/media/effect/effects/SharpenEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.SharpenFilter; + +/** + * @hide + */ +public class SharpenEffect extends SingleFilterEffect { + public SharpenEffect(EffectContext context, String name) { + super(context, name, SharpenFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/StraightenEffect.java b/android/media/effect/effects/StraightenEffect.java new file mode 100644 index 00000000..49253a00 --- /dev/null +++ b/android/media/effect/effects/StraightenEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.StraightenFilter; + +/** + * @hide + */ +public class StraightenEffect extends SingleFilterEffect { + public StraightenEffect(EffectContext context, String name) { + super(context, name, StraightenFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/TintEffect.java b/android/media/effect/effects/TintEffect.java new file mode 100644 index 00000000..6de9ea8f --- /dev/null +++ b/android/media/effect/effects/TintEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.TintFilter; + +/** + * @hide + */ +public class TintEffect extends SingleFilterEffect { + public TintEffect(EffectContext context, String name) { + super(context, name, TintFilter.class, "image", "image"); + } +} diff --git a/android/media/effect/effects/VignetteEffect.java b/android/media/effect/effects/VignetteEffect.java new file mode 100644 index 00000000..b143d775 --- /dev/null +++ b/android/media/effect/effects/VignetteEffect.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 android.media.effect.effects; + +import android.media.effect.EffectContext; +import android.media.effect.SingleFilterEffect; +import android.filterpacks.imageproc.VignetteFilter; + +/** + * @hide + */ +public class VignetteEffect extends SingleFilterEffect { + public VignetteEffect(EffectContext context, String name) { + super(context, name, VignetteFilter.class, "image", "image"); + } +} |