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