SurfaceMediaSource_test.cpp revision 72cecca17d735db6532c45f0a7e10c47ee6f065a
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2011 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "SurfaceMediaSource_test"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gtest/gtest.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/String8.h>
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Errors.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <fcntl.h>
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <unistd.h>
258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
265778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <GLES2/gl2.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
2935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/mediarecorder.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <ui/GraphicBuffer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gui/Surface.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gui/ISurfaceComposer.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gui/Surface.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gui/SurfaceComposerClient.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber#include <binder/ProcessState.h>
382c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber#include <ui/FramebufferNativeWindow.h>
392c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
402c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber#include <media/stagefright/foundation/ADebug.h>
412c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
422c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber#include <media/stagefright/MediaDefs.h>
43c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber#include <media/stagefright/MetaData.h>
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/OMXClient.h>
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/OMXCodec.h>
46f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <OMX_Component.h>
47f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "DummyRecorder.h"
496610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberclass GLTest : public ::testing::Test {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    GLTest():
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mEglDisplay(EGL_NO_DISPLAY),
58c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mEglSurface(EGL_NO_SURFACE),
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mEglContext(EGL_NO_CONTEXT) {
60c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    }
61f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
62c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    virtual void SetUp() {
635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("GLTest::SetUp()");
645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
65f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ASSERT_EQ(EGL_SUCCESS, eglGetError());
665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6803e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        EGLint majorVersion;
6903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        EGLint minorVersion;
70eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
71eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
72eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        RecordProperty("EglVersionMajor", majorVersion);
73eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        RecordProperty("EglVersionMajor", minorVersion);
74eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
75eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        EGLint numConfigs = 0;
76eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
77eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                1, &numConfigs));
78eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
79eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
80eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
81eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        if (displaySecsEnv != NULL) {
82eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber            mDisplaySecs = atoi(displaySecsEnv);
83eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber            if (mDisplaySecs < 0) {
84eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                mDisplaySecs = 0;
85eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber            }
86eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        } else {
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mDisplaySecs = 0;
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mDisplaySecs > 0) {
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mComposerClient = new SurfaceComposerClient;
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
93c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mSurfaceControl = mComposerClient->createSurface(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    String8("Test Surface"),
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    getSurfaceWidth(), getSurfaceHeight(),
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    PIXEL_FORMAT_RGB_888, 0);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_TRUE(mSurfaceControl != NULL);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_TRUE(mSurfaceControl->isValid());
1016610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            SurfaceComposerClient::openGlobalTransaction();
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            SurfaceComposerClient::closeGlobalTransaction();
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<ANativeWindow> window = mSurfaceControl->getSurface();
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    window.get(), NULL);
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGV("No actual display. Choosing EGLSurface based on SurfaceMediaSource");
1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<IGraphicBufferProducer> sms = (new SurfaceMediaSource(
1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getSurfaceWidth(), getSurfaceHeight()))->getBufferQueue();
114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            sp<Surface> stc = new Surface(sms);
115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            sp<ANativeWindow> window = stc;
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
118c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                    window.get(), NULL);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                getContextAttribs());
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
126ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
127ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
128ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
129ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                mEglContext));
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        EGLint w, h;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RecordProperty("EglSurfaceWidth", w);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RecordProperty("EglSurfaceHeight", h);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        glViewport(0, 0, w, h);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void TearDown() {
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Display the result
14635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
14735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            eglSwapBuffers(mEglDisplay, mEglSurface);
14835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            sleep(mDisplaySecs);
14935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        }
15035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
15135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        if (mComposerClient != NULL) {
15235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            mComposerClient->dispose();
15335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        }
15435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        if (mEglContext != EGL_NO_CONTEXT) {
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eglDestroyContext(mEglDisplay, mEglContext);
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mEglSurface != EGL_NO_SURFACE) {
158c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            eglDestroySurface(mEglDisplay, mEglSurface);
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mEglDisplay != EGL_NO_DISPLAY) {
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eglTerminate(mEglDisplay);
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(EGL_SUCCESS, eglGetError());
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    virtual EGLint const* getConfigAttribs() {
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGV("GLTest getConfigAttribs");
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        static EGLint sDefaultConfigAttribs[] = {
169ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
170afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_RED_SIZE, 8,
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_GREEN_SIZE, 8,
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_BLUE_SIZE, 8,
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_ALPHA_SIZE, 8,
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_DEPTH_SIZE, 16,
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_STENCIL_SIZE, 8,
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            EGL_NONE };
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
179dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        return sDefaultConfigAttribs;
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual EGLint const* getContextAttribs() {
18331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        static EGLint sDefaultContextAttribs[] = {
1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            EGL_CONTEXT_CLIENT_VERSION, 2,
18531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            EGL_NONE };
186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return sDefaultContextAttribs;
188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual EGLint getSurfaceWidth() {
191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return 512;
1929806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
1939806555d3930be43e11106281dee354820ac1c88Andreas Huber
1949806555d3930be43e11106281dee354820ac1c88Andreas Huber    virtual EGLint getSurfaceHeight() {
1959806555d3930be43e11106281dee354820ac1c88Andreas Huber        return 512;
1969806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
1979806555d3930be43e11106281dee354820ac1c88Andreas Huber
198e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        GLuint shader = glCreateShader(shaderType);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (shader) {
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            glShaderSource(shader, 1, &pSource, NULL);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            glCompileShader(shader);
205349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            GLint compiled = 0;
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!compiled) {
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                GLint infoLen = 0;
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (infoLen) {
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    char* buf = (char*) malloc(infoLen);
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (buf) {
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        glGetShaderInfoLog(shader, infoLen, NULL, buf);
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        printf("Shader compile log:\n%s\n", buf);
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        free(buf);
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        FAIL();
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    char* buf = (char*) malloc(0x1000);
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (buf) {
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        glGetShaderInfoLog(shader, 0x1000, NULL, buf);
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        printf("Shader compile log:\n%s\n", buf);
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        free(buf);
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        FAIL();
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                glDeleteShader(shader);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                shader = 0;
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ASSERT_TRUE(shader != 0);
235ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        *outShader = shader;
236aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void createProgram(const char* pVertexSource, const char* pFragmentSource,
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            GLuint* outPgm) {
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        GLuint vertexShader, fragmentShader;
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            SCOPED_TRACE("compiling vertex shader");
243729de186450f78c099637e1fce743fe531862c52Andreas Huber            loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
2442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (HasFatalFailure()) {
2452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                return;
2462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
247729de186450f78c099637e1fce743fe531862c52Andreas Huber        }
248729de186450f78c099637e1fce743fe531862c52Andreas Huber        {
249729de186450f78c099637e1fce743fe531862c52Andreas Huber            SCOPED_TRACE("compiling fragment shader");
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (HasFatalFailure()) {
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                return;
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        GLuint program = glCreateProgram();
2577b4262221c06951e9df75d5414c0a7daab365177Andreas Huber        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
2587b4262221c06951e9df75d5414c0a7daab365177Andreas Huber        if (program) {
2597b4262221c06951e9df75d5414c0a7daab365177Andreas Huber            glAttachShader(program, vertexShader);
2607b4262221c06951e9df75d5414c0a7daab365177Andreas Huber            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            glAttachShader(program, fragmentShader);
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            glLinkProgram(program);
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            GLint linkStatus = GL_FALSE;
265bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
266bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            if (linkStatus != GL_TRUE) {
2670ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber                GLint bufLength = 0;
2680ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber                glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (bufLength) {
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    char* buf = (char*) malloc(bufLength);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (buf) {
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        glGetProgramInfoLog(program, bufLength, NULL, buf);
2730ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber                        printf("Program link log:\n%s\n", buf);
2740ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber                        free(buf);
275d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                        FAIL();
2760ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber                    }
277d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                }
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                glDeleteProgram(program);
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                program = 0;
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
281577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        }
28231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        glDeleteShader(vertexShader);
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        glDeleteShader(fragmentShader);
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ASSERT_TRUE(program != 0);
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *outPgm = program;
286cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    }
28703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
288c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    static int abs(int value) {
28903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        return value > 0 ? value : -value;
290ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    }
291ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
292ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    ::testing::AssertionResult checkPixel(int x, int y, int r,
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int g, int b, int a, int tolerance=2) {
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        GLubyte pixel[4];
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        String8 msg;
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        GLenum err = glGetError();
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != GL_NO_ERROR) {
299            msg += String8::format("error reading pixel: %#x", err);
300            while ((err = glGetError()) != GL_NO_ERROR) {
301                msg += String8::format(", %#x", err);
302            }
303            fprintf(stderr, "pixel check failure: %s\n", msg.string());
304            return ::testing::AssertionFailure(
305                    ::testing::Message(msg.string()));
306        }
307        if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
308            msg += String8::format("r(%d isn't %d)", pixel[0], r);
309        }
310        if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
311            if (!msg.isEmpty()) {
312                msg += " ";
313            }
314            msg += String8::format("g(%d isn't %d)", pixel[1], g);
315        }
316        if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
317            if (!msg.isEmpty()) {
318                msg += " ";
319            }
320            msg += String8::format("b(%d isn't %d)", pixel[2], b);
321        }
322        if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
323            if (!msg.isEmpty()) {
324                msg += " ";
325            }
326            msg += String8::format("a(%d isn't %d)", pixel[3], a);
327        }
328        if (!msg.isEmpty()) {
329            fprintf(stderr, "pixel check failure: %s\n", msg.string());
330            return ::testing::AssertionFailure(
331                    ::testing::Message(msg.string()));
332        } else {
333            return ::testing::AssertionSuccess();
334        }
335    }
336
337    int mDisplaySecs;
338    sp<SurfaceComposerClient> mComposerClient;
339    sp<SurfaceControl> mSurfaceControl;
340
341    EGLDisplay mEglDisplay;
342    EGLSurface mEglSurface;
343    EGLContext mEglContext;
344    EGLConfig  mGlConfig;
345};
346
347///////////////////////////////////////////////////////////////////////
348//    Class for  the NON-GL tests
349///////////////////////////////////////////////////////////////////////
350class SurfaceMediaSourceTest : public ::testing::Test {
351public:
352
353    SurfaceMediaSourceTest( ): mYuvTexWidth(176), mYuvTexHeight(144) { }
354    void oneBufferPass(int width, int height );
355    void oneBufferPassNoFill(int width, int height );
356    static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
357    static void fillYV12BufferRect(uint8_t* buf, int w, int h,
358                        int stride, const android_native_rect_t& rect) ;
359protected:
360
361    virtual void SetUp() {
362        android::ProcessState::self()->startThreadPool();
363        mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
364
365        // Manual cast is required to avoid constructor ambiguity
366        mSTC = new Surface(static_cast<sp<IGraphicBufferProducer> >( mSMS->getBufferQueue()));
367        mANW = mSTC;
368    }
369
370    virtual void TearDown() {
371        mSMS.clear();
372        mSTC.clear();
373        mANW.clear();
374    }
375
376    const int mYuvTexWidth;
377    const int mYuvTexHeight;
378
379    sp<SurfaceMediaSource> mSMS;
380    sp<Surface> mSTC;
381    sp<ANativeWindow> mANW;
382};
383
384///////////////////////////////////////////////////////////////////////
385//    Class for  the GL tests
386///////////////////////////////////////////////////////////////////////
387class SurfaceMediaSourceGLTest : public GLTest {
388public:
389
390    SurfaceMediaSourceGLTest( ): mYuvTexWidth(176), mYuvTexHeight(144) { }
391    virtual EGLint const* getConfigAttribs();
392    void oneBufferPassGL(int num = 0);
393    static sp<MediaRecorder> setUpMediaRecorder(int fileDescriptor, int videoSource,
394        int outputFormat, int videoEncoder, int width, int height, int fps);
395protected:
396
397    virtual void SetUp() {
398        ALOGV("SMS-GLTest::SetUp()");
399        android::ProcessState::self()->startThreadPool();
400        mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
401        mSTC = new Surface(static_cast<sp<IGraphicBufferProducer> >( mSMS->getBufferQueue()));
402        mANW = mSTC;
403
404        // Doing the setup related to the GL Side
405        GLTest::SetUp();
406    }
407
408    virtual void TearDown() {
409        mSMS.clear();
410        mSTC.clear();
411        mANW.clear();
412        GLTest::TearDown();
413    }
414
415    void setUpEGLSurfaceFromMediaRecorder(sp<MediaRecorder>& mr);
416
417    const int mYuvTexWidth;
418    const int mYuvTexHeight;
419
420    sp<SurfaceMediaSource> mSMS;
421    sp<Surface> mSTC;
422    sp<ANativeWindow> mANW;
423};
424
425/////////////////////////////////////////////////////////////////////
426// Methods in SurfaceMediaSourceGLTest
427/////////////////////////////////////////////////////////////////////
428EGLint const* SurfaceMediaSourceGLTest::getConfigAttribs() {
429        ALOGV("SurfaceMediaSourceGLTest getConfigAttribs");
430    static EGLint sDefaultConfigAttribs[] = {
431        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
432        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
433        EGL_RED_SIZE, 8,
434        EGL_GREEN_SIZE, 8,
435        EGL_BLUE_SIZE, 8,
436        EGL_RECORDABLE_ANDROID, EGL_TRUE,
437        EGL_NONE };
438
439    return sDefaultConfigAttribs;
440}
441
442// One pass of dequeuing and queuing a GLBuffer
443void SurfaceMediaSourceGLTest::oneBufferPassGL(int num) {
444    int d = num % 50;
445    float f = 0.2f; // 0.1f * d;
446
447    glClearColor(0, 0.3, 0, 0.6);
448    glClear(GL_COLOR_BUFFER_BIT);
449
450    glEnable(GL_SCISSOR_TEST);
451    glScissor(4 + d, 4 + d, 4, 4);
452    glClearColor(1.0 - f, f, f, 1.0);
453    glClear(GL_COLOR_BUFFER_BIT);
454
455    glScissor(24 + d, 48 + d, 4, 4);
456    glClearColor(f, 1.0 - f, f, 1.0);
457    glClear(GL_COLOR_BUFFER_BIT);
458
459    glScissor(37 + d, 17 + d, 4, 4);
460    glClearColor(f, f, 1.0 - f, 1.0);
461    glClear(GL_COLOR_BUFFER_BIT);
462
463    // The following call dequeues and queues the buffer
464    eglSwapBuffers(mEglDisplay, mEglSurface);
465    ASSERT_EQ(EGL_SUCCESS, eglGetError());
466    glDisable(GL_SCISSOR_TEST);
467}
468
469// Set up the MediaRecorder which runs in the same process as mediaserver
470sp<MediaRecorder> SurfaceMediaSourceGLTest::setUpMediaRecorder(int fd, int videoSource,
471        int outputFormat, int videoEncoder, int width, int height, int fps) {
472    sp<MediaRecorder> mr = new MediaRecorder();
473    mr->setVideoSource(videoSource);
474    mr->setOutputFormat(outputFormat);
475    mr->setVideoEncoder(videoEncoder);
476    mr->setOutputFile(fd, 0, 0);
477    mr->setVideoSize(width, height);
478    mr->setVideoFrameRate(fps);
479    mr->prepare();
480    ALOGV("Starting MediaRecorder...");
481    CHECK_EQ((status_t)OK, mr->start());
482    return mr;
483}
484
485// query the mediarecorder for a surfacemeidasource and create an egl surface with that
486void SurfaceMediaSourceGLTest::setUpEGLSurfaceFromMediaRecorder(sp<MediaRecorder>& mr) {
487    sp<IGraphicBufferProducer> iST = mr->querySurfaceMediaSourceFromMediaServer();
488    mSTC = new Surface(iST);
489    mANW = mSTC;
490
491    if (mEglSurface != EGL_NO_SURFACE) {
492        EXPECT_TRUE(eglDestroySurface(mEglDisplay, mEglSurface));
493        mEglSurface = EGL_NO_SURFACE;
494    }
495    mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
496                                mANW.get(), NULL);
497    ASSERT_EQ(EGL_SUCCESS, eglGetError());
498    ASSERT_NE(EGL_NO_SURFACE, mEglSurface) ;
499
500    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
501            mEglContext));
502    ASSERT_EQ(EGL_SUCCESS, eglGetError());
503}
504
505
506/////////////////////////////////////////////////////////////////////
507// Methods in SurfaceMediaSourceTest
508/////////////////////////////////////////////////////////////////////
509
510// One pass of dequeuing and queuing the buffer. Fill it in with
511// cpu YV12 buffer
512void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
513    ANativeWindowBuffer* anb;
514    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
515    ASSERT_TRUE(anb != NULL);
516
517
518    // Fill the buffer with the a checkerboard pattern
519    uint8_t* img = NULL;
520    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
521    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
522    SurfaceMediaSourceTest::fillYV12Buffer(img, width, height, buf->getStride());
523    buf->unlock();
524
525    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
526            -1));
527}
528
529// Dequeuing and queuing the buffer without really filling it in.
530void SurfaceMediaSourceTest::oneBufferPassNoFill(int width, int height ) {
531    ANativeWindowBuffer* anb;
532    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
533    ASSERT_TRUE(anb != NULL);
534
535    // We do not fill the buffer in. Just queue it back.
536    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
537    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
538            -1));
539}
540
541// Fill a YV12 buffer with a multi-colored checkerboard pattern
542void SurfaceMediaSourceTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
543    const int blockWidth = w > 16 ? w / 16 : 1;
544    const int blockHeight = h > 16 ? h / 16 : 1;
545    const int yuvTexOffsetY = 0;
546    int yuvTexStrideY = stride;
547    int yuvTexOffsetV = yuvTexStrideY * h;
548    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
549    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
550    int yuvTexStrideU = yuvTexStrideV;
551    for (int x = 0; x < w; x++) {
552        for (int y = 0; y < h; y++) {
553            int parityX = (x / blockWidth) & 1;
554            int parityY = (y / blockHeight) & 1;
555            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
556            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
557            if (x < w / 2 && y < h / 2) {
558                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
559                if (x * 2 < w / 2 && y * 2 < h / 2) {
560                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
561                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
562                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
563                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
564                        intensity;
565                }
566            }
567        }
568    }
569}
570
571// Fill a YV12 buffer with red outside a given rectangle and green inside it.
572void SurfaceMediaSourceTest::fillYV12BufferRect(uint8_t* buf, int w,
573                  int h, int stride, const android_native_rect_t& rect) {
574    const int yuvTexOffsetY = 0;
575    int yuvTexStrideY = stride;
576    int yuvTexOffsetV = yuvTexStrideY * h;
577    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
578    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
579    int yuvTexStrideU = yuvTexStrideV;
580    for (int x = 0; x < w; x++) {
581        for (int y = 0; y < h; y++) {
582            bool inside = rect.left <= x && x < rect.right &&
583                    rect.top <= y && y < rect.bottom;
584            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
585            if (x < w / 2 && y < h / 2) {
586                bool inside = rect.left <= 2*x && 2*x < rect.right &&
587                        rect.top <= 2*y && 2*y < rect.bottom;
588                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
589                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
590                                                inside ? 16 : 255;
591            }
592        }
593    }
594}  ///////// End of class SurfaceMediaSourceTest
595
596///////////////////////////////////////////////////////////////////
597// Class to imitate the recording     /////////////////////////////
598// ////////////////////////////////////////////////////////////////
599struct SimpleDummyRecorder {
600        sp<MediaSource> mSource;
601
602        SimpleDummyRecorder
603                (const sp<MediaSource> &source): mSource(source) {}
604
605        status_t start() { return mSource->start();}
606        status_t stop()  { return mSource->stop();}
607
608        // fakes reading from a media source
609        status_t readFromSource() {
610            MediaBuffer *buffer;
611            status_t err = mSource->read(&buffer);
612            if (err != OK) {
613                return err;
614            }
615            buffer->release();
616            buffer = NULL;
617            return OK;
618        }
619};
620///////////////////////////////////////////////////////////////////
621//           TESTS
622// SurfaceMediaSourceTest class contains tests that fill the buffers
623// using the cpu calls
624// SurfaceMediaSourceGLTest class contains tests that fill the buffers
625// using the GL calls.
626// TODO: None of the tests actually verify the encoded images.. so at this point,
627// these are mostly functionality tests + visual inspection
628//////////////////////////////////////////////////////////////////////
629
630// Just pass one buffer from the native_window to the SurfaceMediaSource
631// Dummy Encoder
632static int testId = 1;
633TEST_F(SurfaceMediaSourceTest, DISABLED_DummyEncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
634    ALOGV("Test # %d", testId++);
635    ALOGV("Testing OneBufferPass ******************************");
636
637    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
638            HAL_PIXEL_FORMAT_YV12));
639    oneBufferPass(mYuvTexWidth, mYuvTexHeight);
640}
641
642// Pass the buffer with the wrong height and weight and should not be accepted
643// Dummy Encoder
644TEST_F(SurfaceMediaSourceTest, DISABLED_DummyEncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
645    ALOGV("Test # %d", testId++);
646    ALOGV("Testing Wrong size BufferPass ******************************");
647
648    // setting the client side buffer size different than the server size
649    ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
650             10, 10));
651    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
652            HAL_PIXEL_FORMAT_YV12));
653
654    ANativeWindowBuffer* anb;
655
656    // Note: make sure we get an ERROR back when dequeuing!
657    ASSERT_NE(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
658}
659
660// pass multiple buffers from the native_window the SurfaceMediaSource
661// Dummy Encoder
662TEST_F(SurfaceMediaSourceTest,  DISABLED_DummyEncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
663    ALOGV("Test # %d", testId++);
664    ALOGV("Testing MultiBufferPass, Dummy Recorder *********************");
665    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
666            HAL_PIXEL_FORMAT_YV12));
667
668    SimpleDummyRecorder writer(mSMS);
669    writer.start();
670
671    int32_t nFramesCount = 0;
672    while (nFramesCount < 300) {
673        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
674
675        ASSERT_EQ(NO_ERROR, writer.readFromSource());
676
677        nFramesCount++;
678    }
679    writer.stop();
680}
681
682// Delayed pass of multiple buffers from the native_window the SurfaceMediaSource
683// Dummy Encoder
684TEST_F(SurfaceMediaSourceTest,  DummyLagEncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
685    ALOGV("Test # %d", testId++);
686    ALOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
687
688    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
689            HAL_PIXEL_FORMAT_YV12));
690
691    SimpleDummyRecorder writer(mSMS);
692    writer.start();
693
694    int32_t nFramesCount = 1;
695    const int FRAMES_LAG = SurfaceMediaSource::MIN_UNDEQUEUED_BUFFERS;
696
697    while (nFramesCount <= 300) {
698        ALOGV("Frame: %d", nFramesCount);
699        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
700        // Forcing the writer to lag behind a few frames
701        if (nFramesCount > FRAMES_LAG) {
702            ASSERT_EQ(NO_ERROR, writer.readFromSource());
703        }
704        nFramesCount++;
705    }
706    writer.stop();
707}
708
709// pass multiple buffers from the native_window the SurfaceMediaSource
710// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
711TEST_F(SurfaceMediaSourceTest, DummyThreadedEncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
712    ALOGV("Test # %d", testId++);
713    ALOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
714    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
715            HAL_PIXEL_FORMAT_YV12));
716
717    DummyRecorder writer(mSMS);
718    writer.start();
719
720    int32_t nFramesCount = 0;
721    while (nFramesCount <= 300) {
722        ALOGV("Frame: %d", nFramesCount);
723        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
724
725        nFramesCount++;
726    }
727    writer.stop();
728}
729
730// Test to examine actual encoding using mediarecorder
731// We use the mediaserver to create a mediarecorder and send
732// it back to us. So SurfaceMediaSource lives in the same process
733// as the mediaserver.
734// Very close to the actual camera, except that the
735// buffers are filled and queueud by the CPU instead of GL.
736TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuYV12BufferNpotWriteMediaServer) {
737    ALOGV("Test # %d", testId++);
738    ALOGV("************** Testing the whole pipeline with actual MediaRecorder ***********");
739    ALOGV("************** SurfaceMediaSource is same process as mediaserver    ***********");
740
741    const char *fileName = "/sdcard/outputSurfEncMSource.mp4";
742    int fd = open(fileName, O_RDWR | O_CREAT, 0744);
743    if (fd < 0) {
744        ALOGE("ERROR: Could not open the the file %s, fd = %d !!", fileName, fd);
745    }
746    CHECK(fd >= 0);
747
748    sp<MediaRecorder> mr = SurfaceMediaSourceGLTest::setUpMediaRecorder(fd,
749            VIDEO_SOURCE_SURFACE, OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264,
750            mYuvTexWidth, mYuvTexHeight, 30);
751    // get the reference to the surfacemediasource living in
752    // mediaserver that is created by stagefrightrecorder
753    sp<IGraphicBufferProducer> iST = mr->querySurfaceMediaSourceFromMediaServer();
754    mSTC = new Surface(iST);
755    mANW = mSTC;
756    ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
757    ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
758                                                HAL_PIXEL_FORMAT_YV12));
759
760    int32_t nFramesCount = 0;
761    while (nFramesCount <= 300) {
762        oneBufferPassNoFill(mYuvTexWidth, mYuvTexHeight);
763        nFramesCount++;
764        ALOGV("framesCount = %d", nFramesCount);
765    }
766
767    ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU));
768    ALOGV("Stopping MediaRecorder...");
769    CHECK_EQ((status_t)OK, mr->stop());
770    mr.clear();
771    close(fd);
772}
773
774//////////////////////////////////////////////////////////////////////
775// GL tests
776/////////////////////////////////////////////////////////////////////
777
778// Test to examine whether we can choose the Recordable Android GLConfig
779// DummyRecorder used- no real encoding here
780TEST_F(SurfaceMediaSourceGLTest, ChooseAndroidRecordableEGLConfigDummyWriter) {
781    ALOGV("Test # %d", testId++);
782    ALOGV("Verify creating a surface w/ right config + dummy writer*********");
783
784    mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
785    mSTC = new Surface(static_cast<sp<IGraphicBufferProducer> >( mSMS->getBufferQueue()));
786    mANW = mSTC;
787
788    DummyRecorder writer(mSMS);
789    writer.start();
790
791    if (mEglSurface != EGL_NO_SURFACE) {
792        EXPECT_TRUE(eglDestroySurface(mEglDisplay, mEglSurface));
793        mEglSurface = EGL_NO_SURFACE;
794    }
795
796    mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
797                                mANW.get(), NULL);
798    ASSERT_EQ(EGL_SUCCESS, eglGetError());
799    ASSERT_NE(EGL_NO_SURFACE, mEglSurface) ;
800
801    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
802            mEglContext));
803    ASSERT_EQ(EGL_SUCCESS, eglGetError());
804
805    int32_t nFramesCount = 0;
806    while (nFramesCount <= 300) {
807        oneBufferPassGL();
808        nFramesCount++;
809        ALOGV("framesCount = %d", nFramesCount);
810    }
811
812    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
813            EGL_NO_CONTEXT));
814    ASSERT_EQ(EGL_SUCCESS, eglGetError());
815    eglDestroySurface(mEglDisplay, mEglSurface);
816    mEglSurface = EGL_NO_SURFACE;
817
818    writer.stop();
819}
820// Test to examine whether we can render GL buffers in to the surface
821// created with the native window handle
822TEST_F(SurfaceMediaSourceGLTest, RenderingToRecordableEGLSurfaceWorks) {
823    ALOGV("Test # %d", testId++);
824    ALOGV("RenderingToRecordableEGLSurfaceWorks *********************");
825    // Do the producer side of things
826    glClearColor(0.6, 0.6, 0.6, 0.6);
827    glClear(GL_COLOR_BUFFER_BIT);
828
829    glEnable(GL_SCISSOR_TEST);
830    glScissor(4, 4, 4, 4);
831    glClearColor(1.0, 0.0, 0.0, 1.0);
832    glClear(GL_COLOR_BUFFER_BIT);
833
834    glScissor(24, 48, 4, 4);
835    glClearColor(0.0, 1.0, 0.0, 1.0);
836    glClear(GL_COLOR_BUFFER_BIT);
837
838    glScissor(37, 17, 4, 4);
839    glClearColor(0.0, 0.0, 1.0, 1.0);
840    glClear(GL_COLOR_BUFFER_BIT);
841
842    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
843    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
844    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
845    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
846
847    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
848    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
849    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
850    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
851    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
852    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
853    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
854    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
855    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
856    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
857    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
858    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
859    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
860    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
861    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
862    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
863}
864
865// Test to examine the actual encoding with GL buffers
866// Actual encoder, Actual GL Buffers Filled SurfaceMediaSource
867// The same pattern is rendered every frame
868TEST_F(SurfaceMediaSourceGLTest, EncodingFromGLRgbaSameImageEachBufNpotWrite) {
869    ALOGV("Test # %d", testId++);
870    ALOGV("************** Testing the whole pipeline with actual Recorder ***********");
871    ALOGV("************** GL Filling the buffers ***********");
872    // Note: No need to set the colorformat for the buffers. The colorformat is
873    // in the GRAlloc buffers itself.
874
875    const char *fileName = "/sdcard/outputSurfEncMSourceGL.mp4";
876    int fd = open(fileName, O_RDWR | O_CREAT, 0744);
877    if (fd < 0) {
878        ALOGE("ERROR: Could not open the the file %s, fd = %d !!", fileName, fd);
879    }
880    CHECK(fd >= 0);
881
882    sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_SURFACE,
883            OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth, mYuvTexHeight, 30);
884
885    // get the reference to the surfacemediasource living in
886    // mediaserver that is created by stagefrightrecorder
887    setUpEGLSurfaceFromMediaRecorder(mr);
888
889    int32_t nFramesCount = 0;
890    while (nFramesCount <= 300) {
891        oneBufferPassGL();
892        nFramesCount++;
893        ALOGV("framesCount = %d", nFramesCount);
894    }
895
896    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
897            EGL_NO_CONTEXT));
898    ASSERT_EQ(EGL_SUCCESS, eglGetError());
899    eglDestroySurface(mEglDisplay, mEglSurface);
900    mEglSurface = EGL_NO_SURFACE;
901
902    ALOGV("Stopping MediaRecorder...");
903    CHECK_EQ((status_t)OK, mr->stop());
904    mr.clear();
905    close(fd);
906}
907
908// Test to examine the actual encoding from the GL Buffers
909// Actual encoder, Actual GL Buffers Filled SurfaceMediaSource
910// A different pattern is rendered every frame
911TEST_F(SurfaceMediaSourceGLTest, EncodingFromGLRgbaDiffImageEachBufNpotWrite) {
912    ALOGV("Test # %d", testId++);
913    ALOGV("************** Testing the whole pipeline with actual Recorder ***********");
914    ALOGV("************** Diff GL Filling the buffers ***********");
915    // Note: No need to set the colorformat for the buffers. The colorformat is
916    // in the GRAlloc buffers itself.
917
918    const char *fileName = "/sdcard/outputSurfEncMSourceGLDiff.mp4";
919    int fd = open(fileName, O_RDWR | O_CREAT, 0744);
920    if (fd < 0) {
921        ALOGE("ERROR: Could not open the the file %s, fd = %d !!", fileName, fd);
922    }
923    CHECK(fd >= 0);
924
925    sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_SURFACE,
926            OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth, mYuvTexHeight, 30);
927
928    // get the reference to the surfacemediasource living in
929    // mediaserver that is created by stagefrightrecorder
930    setUpEGLSurfaceFromMediaRecorder(mr);
931
932    int32_t nFramesCount = 0;
933    while (nFramesCount <= 300) {
934        oneBufferPassGL(nFramesCount);
935        nFramesCount++;
936        ALOGV("framesCount = %d", nFramesCount);
937    }
938
939    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
940            EGL_NO_CONTEXT));
941    ASSERT_EQ(EGL_SUCCESS, eglGetError());
942    eglDestroySurface(mEglDisplay, mEglSurface);
943    mEglSurface = EGL_NO_SURFACE;
944
945    ALOGV("Stopping MediaRecorder...");
946    CHECK_EQ((status_t)OK, mr->stop());
947    mr.clear();
948    close(fd);
949}
950} // namespace android
951