yangkang2021.github.io

webrtc-视频渲染的缩放类型ScaleType

webrtc视频渲染经常调整渲染方式,看看webrtc下怎么做:

一. ios的opengl或者Metal

由用户调整RTCVideoRenderer在父视图中的显示区域bounds完成。

….. }


### 二. android的SurfaceViewRenderer
> - 通过onMeasure调整view的实现
> - 可以根据父容器自动调整view的大小,不用sdk用户在重新计算
> - 所以SurfaceViewRenderer要放到一个更大的父容器里面且高宽是wrap_content,才能实现保持比例显示全部画面SCALE_ASPECT_FIT

- SurfaceViewRenderer.java缩放控制参数
renderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT,RendererCommon.ScalingType.SCALE_ASPECT_FIT); ```

//videoLayoutMeasure.measure public Point measure(int widthSpec, int heightSpec, int frameWidth, int frameHeight) { // Calculate max allowed layout size. final int maxWidth = View.getDefaultSize(Integer.MAX_VALUE, widthSpec); final int maxHeight = View.getDefaultSize(Integer.MAX_VALUE, heightSpec); if (frameWidth == 0 || frameHeight == 0 || maxWidth == 0 || maxHeight == 0) { return new Point(maxWidth, maxHeight); } // Calculate desired display size based on scaling type, video aspect ratio, // and maximum layout size. final float frameAspect = frameWidth / (float) frameHeight; final float displayAspect = maxWidth / (float) maxHeight; final float visibleFraction = (frameAspect > 1.0f) == (displayAspect > 1.0f) ? visibleFractionMatchOrientation : visibleFractionMismatchOrientation; final Point layoutSize = getDisplaySize(visibleFraction, frameAspect, maxWidth, maxHeight);

  // If the measure specification is forcing a specific size - yield.
  if (View.MeasureSpec.getMode(widthSpec) == View.MeasureSpec.EXACTLY) {
    layoutSize.x = maxWidth;
  }
  if (View.MeasureSpec.getMode(heightSpec) == View.MeasureSpec.EXACTLY) {
    layoutSize.y = maxHeight;
  }
  return layoutSize;
} ```

private void updateSurfaceSize() { ThreadUtils.checkIsOnMainThread(); if (enableFixedSize && rotatedFrameWidth != 0 && rotatedFrameHeight != 0 && getWidth() != 0 && getHeight() != 0) { final float layoutAspectRatio = getWidth() / (float) getHeight(); final float frameAspectRatio = rotatedFrameWidth / (float) rotatedFrameHeight; final int drawnFrameWidth; final int drawnFrameHeight; if (frameAspectRatio > layoutAspectRatio) { drawnFrameWidth = (int) (rotatedFrameHeight * layoutAspectRatio); drawnFrameHeight = rotatedFrameHeight; } else { drawnFrameWidth = rotatedFrameWidth; drawnFrameHeight = (int) (rotatedFrameWidth / layoutAspectRatio); } // Aspect ratio of the drawn frame and the view is the same. final int width = Math.min(getWidth(), drawnFrameWidth); final int height = Math.min(getHeight(), drawnFrameHeight); logD(“updateSurfaceSize. Layout size: “ + getWidth() + “x” + getHeight() + “, frame size: “ + rotatedFrameWidth + “x” + rotatedFrameHeight + “, requested surface size: “ + width + “x” + height + “, old surface size: “ + surfaceWidth + “x” + surfaceHeight); if (width != surfaceWidth || height != surfaceHeight) { surfaceWidth = width; surfaceHeight = height; getHolder().setFixedSize(width, height); } } else { surfaceWidth = surfaceHeight = 0; getHolder().setSizeFromLayout(); } } ```

三. GDI