Allow Android apps to set video renderer scaling type.

Also add type check for EGL context object received from apps and
switch to byte buffer video decoding if EGL context is incorrect

BUG=3851
R=tkchin@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/25669004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7326 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
glaznev@webrtc.org
2014-09-29 23:07:08 +00:00
parent 7dfb7fa189
commit 359d720004
3 changed files with 32 additions and 19 deletions

View File

@ -78,7 +78,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
// clipped. // clipped.
// SCALE_FILL - video frame is scaled to to fill the size of the view. Video // SCALE_FILL - video frame is scaled to to fill the size of the view. Video
// aspect ratio is changed if necessary. // aspect ratio is changed if necessary.
private static enum ScalingType public static enum ScalingType
{ SCALE_ASPECT_FIT, SCALE_ASPECT_FILL, SCALE_FILL }; { SCALE_ASPECT_FIT, SCALE_ASPECT_FILL, SCALE_FILL };
private final String VERTEX_SHADER_STRING = private final String VERTEX_SHADER_STRING =
@ -244,9 +244,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
private float texTop; private float texTop;
private float texBottom; private float texBottom;
private FloatBuffer textureVertices; private FloatBuffer textureVertices;
// Texture UV coordinates offsets. // Texture UV coordinates.
private float texOffsetU;
private float texOffsetV;
private FloatBuffer textureCoords; private FloatBuffer textureCoords;
// Flag if texture vertices or coordinates update is needed. // Flag if texture vertices or coordinates update is needed.
private boolean updateTextureProperties; private boolean updateTextureProperties;
@ -279,13 +277,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
}; };
textureVertices = directNativeFloatBuffer(textureVeticesFloat); textureVertices = directNativeFloatBuffer(textureVeticesFloat);
// Create texture UV coordinates. // Create texture UV coordinates.
texOffsetU = 0;
texOffsetV = 0;
float textureCoordinatesFloat[] = new float[] { float textureCoordinatesFloat[] = new float[] {
texOffsetU, texOffsetV, // left top 0, 0, 0, 1, 1, 0, 1, 1
texOffsetU, 1.0f - texOffsetV, // left bottom
1.0f - texOffsetU, texOffsetV, // right top
1.0f - texOffsetU, 1.0f - texOffsetV // right bottom
}; };
textureCoords = directNativeFloatBuffer(textureCoordinatesFloat); textureCoords = directNativeFloatBuffer(textureCoordinatesFloat);
updateTextureProperties = false; updateTextureProperties = false;
@ -328,6 +321,9 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
float texBottom = this.texBottom; float texBottom = this.texBottom;
float displayWidth = (texRight - texLeft) * screenWidth / 2; float displayWidth = (texRight - texLeft) * screenWidth / 2;
float displayHeight = (texTop - texBottom) * screenHeight / 2; float displayHeight = (texTop - texBottom) * screenHeight / 2;
Log.d(TAG, "ID: " + id + ". Display: " + displayWidth +
" x " + displayHeight + ". Video: " + videoWidth +
" x " + videoHeight);
if (displayWidth > 1 && displayHeight > 1 && if (displayWidth > 1 && displayHeight > 1 &&
videoWidth > 1 && videoHeight > 1) { videoWidth > 1 && videoHeight > 1) {
float displayAspectRatio = displayWidth / displayHeight; float displayAspectRatio = displayWidth / displayHeight;
@ -345,6 +341,8 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
texTop -= deltaY; texTop -= deltaY;
texBottom += deltaY; texBottom += deltaY;
} }
Log.d(TAG, " Texture vertices: (" + texLeft + "," + texBottom +
") - (" + texRight + "," + texTop + ")");
// Re-allocate vertices buffer to adjust to video aspect ratio. // Re-allocate vertices buffer to adjust to video aspect ratio.
float textureVeticesFloat[] = new float[] { float textureVeticesFloat[] = new float[] {
texLeft, texTop, texLeft, texTop,
@ -355,12 +353,15 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
textureVertices = directNativeFloatBuffer(textureVeticesFloat); textureVertices = directNativeFloatBuffer(textureVeticesFloat);
} }
if (scalingType == ScalingType.SCALE_ASPECT_FILL) { if (scalingType == ScalingType.SCALE_ASPECT_FILL) {
float texOffsetU = 0;
float texOffsetV = 0;
// Need to re-adjust UV coordinates to match display AR. // Need to re-adjust UV coordinates to match display AR.
if (displayAspectRatio > videoAspectRatio) { if (displayAspectRatio > videoAspectRatio) {
texOffsetV = (1.0f - videoAspectRatio / displayAspectRatio) / 2.0f; texOffsetV = (1.0f - videoAspectRatio / displayAspectRatio) / 2.0f;
} else { } else {
texOffsetU = (1.0f - displayAspectRatio / videoAspectRatio) / 2.0f; texOffsetU = (1.0f - displayAspectRatio / videoAspectRatio) / 2.0f;
} }
Log.d(TAG, " Texture UV offsets: " + texOffsetU + ", " + texOffsetV);
// Re-allocate coordinates buffer to adjust to display aspect ratio. // Re-allocate coordinates buffer to adjust to display aspect ratio.
float textureCoordinatesFloat[] = new float[] { float textureCoordinatesFloat[] = new float[] {
texOffsetU, texOffsetV, // left top texOffsetU, texOffsetV, // left top
@ -575,14 +576,15 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
* (width, height). All parameters are in percentage of screen resolution. * (width, height). All parameters are in percentage of screen resolution.
*/ */
public static VideoRenderer createGui( public static VideoRenderer createGui(
int x, int y, int width, int height) throws Exception { int x, int y, int width, int height, ScalingType scalingType)
YuvImageRenderer javaGuiRenderer = create(x, y, width, height); throws Exception {
YuvImageRenderer javaGuiRenderer = create(x, y, width, height, scalingType);
return new VideoRenderer(javaGuiRenderer); return new VideoRenderer(javaGuiRenderer);
} }
public static VideoRenderer.Callbacks createGuiRenderer( public static VideoRenderer.Callbacks createGuiRenderer(
int x, int y, int width, int height) { int x, int y, int width, int height, ScalingType scalingType) {
return create(x, y, width, height); return create(x, y, width, height, scalingType);
} }
/** /**
@ -591,7 +593,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
* screen resolution. * screen resolution.
*/ */
public static YuvImageRenderer create( public static YuvImageRenderer create(
int x, int y, int width, int height) { int x, int y, int width, int height, ScalingType scalingType) {
// Check display region parameters. // Check display region parameters.
if (x < 0 || x > 100 || y < 0 || y > 100 || if (x < 0 || x > 100 || y < 0 || y > 100 ||
width < 0 || width > 100 || height < 0 || height > 100 || width < 0 || width > 100 || height < 0 || height > 100 ||
@ -605,7 +607,7 @@ public class VideoRendererGui implements GLSurfaceView.Renderer {
} }
final YuvImageRenderer yuvImageRenderer = new YuvImageRenderer( final YuvImageRenderer yuvImageRenderer = new YuvImageRenderer(
instance.surface, instance.yuvImageRenderers.size(), instance.surface, instance.yuvImageRenderers.size(),
x, y, width, height, ScalingType.SCALE_ASPECT_FIT); x, y, width, height, scalingType);
synchronized (instance.yuvImageRenderers) { synchronized (instance.yuvImageRenderers) {
if (instance.onSurfaceCreatedCalled) { if (instance.onSurfaceCreatedCalled) {
// onSurfaceCreated has already been called for VideoRendererGui - // onSurfaceCreated has already been called for VideoRendererGui -

View File

@ -2055,8 +2055,17 @@ int MediaCodecVideoDecoder::SetAndroidObjects(JNIEnv* jni,
render_egl_context_ = NULL; render_egl_context_ = NULL;
} else { } else {
render_egl_context_ = jni->NewGlobalRef(render_egl_context); render_egl_context_ = jni->NewGlobalRef(render_egl_context);
CHECK_EXCEPTION(jni) << "error calling NewGlobalRef for EGL Context.";
jclass j_egl_context_class = FindClass(jni, "android/opengl/EGLContext");
if (!jni->IsInstanceOf(render_egl_context_, j_egl_context_class)) {
ALOGE("Wrong EGL Context.");
jni->DeleteGlobalRef(render_egl_context_);
render_egl_context_ = NULL;
}
}
if (render_egl_context_ == NULL) {
ALOGD("NULL VideoDecoder EGL context - HW surface decoding is disabled.");
} }
ALOGD("VideoDecoder EGL context set.");
return 0; return 0;
} }

View File

@ -113,8 +113,10 @@ public class AppRTCDemoActivity extends Activity
vsv = new AppRTCGLView(this, displaySize); vsv = new AppRTCGLView(this, displaySize);
VideoRendererGui.setView(vsv); VideoRendererGui.setView(vsv);
remoteRender = VideoRendererGui.create(0, 0, 100, 100); remoteRender = VideoRendererGui.create(0, 0, 100, 100,
localRender = VideoRendererGui.create(70, 5, 25, 25); VideoRendererGui.ScalingType.SCALE_ASPECT_FIT);
localRender = VideoRendererGui.create(70, 5, 25, 25,
VideoRendererGui.ScalingType.SCALE_ASPECT_FIT);
vsv.setOnClickListener(new View.OnClickListener() { vsv.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) { @Override public void onClick(View v) {