165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/*
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License");
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License.
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *      http://www.apache.org/licenses/LICENSE-2.0
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS,
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage android.media.effect.effects;
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.Filter;
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.OneShotScheduler;
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.media.effect.EffectContext;
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.media.effect.FilterGraphEffect;
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.media.effect.EffectUpdateListener;
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterpacks.videoproc.BackDropperFilter;
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterpacks.videoproc.BackDropperFilter.LearningDoneListener;
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Background replacement Effect.
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Replaces the background of the input video stream with a selected video
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Learns the background when it first starts up;
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * needs unobstructed view of background when this happens.
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Effect parameters:
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *   source: A URI for the background video
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Listener: Called when learning period is complete
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @hide
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpublic class BackDropperEffect extends FilterGraphEffect {
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    private static final String mGraphDefinition =
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@import android.filterpacks.base;\n" +
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@import android.filterpacks.videoproc;\n" +
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@import android.filterpacks.videosrc;\n" +
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "\n" +
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@filter GLTextureSource foreground {\n" +
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  texId = 0;\n" + // Will be set by base class
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  width = 0;\n" +
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  height = 0;\n" +
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  repeatFrame = true;\n" +
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "}\n" +
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "\n" +
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@filter MediaSource background {\n" +
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  sourceUrl = \"no_file_specified\";\n" +
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  waitForNewFrame = false;\n" +
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  sourceIsUrl = true;\n" +
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "}\n" +
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "\n" +
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@filter BackDropperFilter replacer {\n" +
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  autowbToggle = 1;\n" +
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "}\n" +
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "\n" +
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@filter GLTextureTarget output {\n" +
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "  texId = 0;\n" +
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "}\n" +
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "\n" +
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@connect foreground[frame]  => replacer[video];\n" +
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@connect background[video]  => replacer[background];\n" +
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            "@connect replacer[video]    => output[frame];\n";
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    private EffectUpdateListener mEffectListener = null;
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    private LearningDoneListener mLearningListener = new LearningDoneListener() {
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        public void onLearningDone(BackDropperFilter filter) {
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            if (mEffectListener != null) {
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                mEffectListener.onEffectUpdated(BackDropperEffect.this, null);
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            }
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        }
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    };
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    public BackDropperEffect(EffectContext context, String name) {
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        super(context, name, mGraphDefinition, "foreground", "output", OneShotScheduler.class);
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        Filter replacer = mGraph.getFilter("replacer");
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        replacer.setInputValue("learningDoneListener", mLearningListener);
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    @Override
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    public void setParameter(String parameterKey, Object value) {
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        if (parameterKey.equals("source")) {
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            Filter background = mGraph.getFilter("background");
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn            background.setInputValue("sourceUrl", value);
94f330d19a17ebdaabdad4e97222f65e7b580abe76Mike Dodd        } else if (parameterKey.equals("context")) {
95f330d19a17ebdaabdad4e97222f65e7b580abe76Mike Dodd            Filter background = mGraph.getFilter("background");
96f330d19a17ebdaabdad4e97222f65e7b580abe76Mike Dodd            background.setInputValue("context", value);
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        }
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    @Override
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    public void setUpdateListener(EffectUpdateListener listener) {
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        mEffectListener = listener;
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}