1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.media.filterpacks.transform; 18 19 import androidx.media.filterfw.Filter; 20 import androidx.media.filterfw.FrameImage2D; 21 import androidx.media.filterfw.FrameType; 22 import androidx.media.filterfw.ImageShader; 23 import androidx.media.filterfw.InputPort; 24 import androidx.media.filterfw.MffContext; 25 import androidx.media.filterfw.OutputPort; 26 import androidx.media.filterfw.Signature; 27 import androidx.media.filterfw.geometry.Quad; 28 29 public class RotateFilter extends Filter { 30 31 private Quad mSourceRect = Quad.fromRect(0f, 0f, 1f, 1f); 32 private float mRotateAngle = 0; 33 private ImageShader mShader; 34 35 public RotateFilter(MffContext context, String name) { 36 super(context, name); 37 } 38 39 @Override 40 public Signature getSignature() { 41 FrameType imageIn = FrameType.image2D(FrameType.ELEMENT_RGBA8888, FrameType.READ_GPU); 42 FrameType imageOut = FrameType.image2D(FrameType.ELEMENT_RGBA8888, FrameType.WRITE_GPU); 43 return new Signature() 44 .addInputPort("image", Signature.PORT_REQUIRED, imageIn) 45 .addInputPort("rotateAngle", Signature.PORT_REQUIRED, FrameType.single(float.class)) 46 .addInputPort("sourceRect", Signature.PORT_OPTIONAL, FrameType.single(Quad.class)) 47 .addOutputPort("image", Signature.PORT_REQUIRED, imageOut) 48 .disallowOtherPorts(); 49 } 50 51 @Override 52 public void onInputPortOpen(InputPort port) { 53 if (port.getName().equals("rotateAngle")) { 54 port.bindToFieldNamed("mRotateAngle"); 55 port.setAutoPullEnabled(true); 56 } else if (port.getName().equals("sourceRect")) { 57 port.bindToFieldNamed("mSourceRect"); 58 port.setAutoPullEnabled(true); 59 } 60 } 61 62 @Override 63 protected void onPrepare() { 64 mShader = ImageShader.createIdentity(); 65 } 66 67 @Override 68 protected void onProcess() { 69 OutputPort outPort = getConnectedOutputPort("image"); 70 FrameImage2D inputImage = getConnectedInputPort("image").pullFrame().asFrameImage2D(); 71 int[] inDims = inputImage.getDimensions(); 72 73 FrameImage2D outputImage = outPort.fetchAvailableFrame(inDims).asFrameImage2D(); 74 mShader.setSourceQuad(mSourceRect); 75 Quad targetQuad = mSourceRect.rotated((float) (mRotateAngle / 180 * Math.PI)); 76 mShader.setTargetQuad(targetQuad); 77 mShader.process(inputImage, outputImage); 78 outPort.pushFrame(outputImage); 79 } 80 } 81