123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * Copyright (C) 2015 Bilibili
- * Copyright (C) 2015 Zhang Rui <bbcallen@gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.edufound.reader.ijkplayer.media;
- import android.view.View;
- import java.lang.ref.WeakReference;
- public final class MeasureHelper {
- private WeakReference<View> mWeakView;
- private int mVideoWidth;
- private int mVideoHeight;
- private int mVideoSarNum;
- private int mVideoSarDen;
- private int mVideoRotationDegree;
- private int mMeasuredWidth;
- private int mMeasuredHeight;
- private int mCurrentAspectRatio = IRenderView.AR_ASPECT_FIT_PARENT;
- public MeasureHelper(View view) {
- mWeakView = new WeakReference<View>(view);
- }
- public View getView() {
- if (mWeakView == null)
- return null;
- return mWeakView.get();
- }
- public void setVideoSize(int videoWidth, int videoHeight) {
- mVideoWidth = videoWidth;
- mVideoHeight = videoHeight;
- }
- public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) {
- mVideoSarNum = videoSarNum;
- mVideoSarDen = videoSarDen;
- }
- public void setVideoRotation(int videoRotationDegree) {
- mVideoRotationDegree = videoRotationDegree;
- }
- /**
- * Must be called by View.onMeasure(int, int)
- *
- * @param widthMeasureSpec
- * @param heightMeasureSpec
- */
- public void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
- // + MeasureSpec.toString(heightMeasureSpec) + ")");
- if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
- int tempSpec = widthMeasureSpec;
- widthMeasureSpec = heightMeasureSpec;
- heightMeasureSpec = tempSpec;
- }
- int width = View.getDefaultSize(mVideoWidth, widthMeasureSpec);
- int height = View.getDefaultSize(mVideoHeight, heightMeasureSpec);
- if (mCurrentAspectRatio == IRenderView.AR_MATCH_PARENT) {
- width = widthMeasureSpec;
- height = heightMeasureSpec;
- } else if (mVideoWidth > 0 && mVideoHeight > 0) {
- int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);
- int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);
- int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);
- int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);
- if (widthSpecMode == View.MeasureSpec.AT_MOST && heightSpecMode == View.MeasureSpec.AT_MOST) {
- float specAspectRatio = (float) widthSpecSize / (float) heightSpecSize;
- float displayAspectRatio;
- switch (mCurrentAspectRatio) {
- case IRenderView.AR_16_9_FIT_PARENT:
- displayAspectRatio = 16.0f / 9.0f;
- if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270)
- displayAspectRatio = 1.0f / displayAspectRatio;
- break;
- case IRenderView.AR_4_3_FIT_PARENT:
- displayAspectRatio = 4.0f / 3.0f;
- if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270)
- displayAspectRatio = 1.0f / displayAspectRatio;
- break;
- case IRenderView.AR_ASPECT_FIT_PARENT:
- case IRenderView.AR_ASPECT_FILL_PARENT:
- case IRenderView.AR_ASPECT_WRAP_CONTENT:
- default:
- displayAspectRatio = (float) mVideoWidth / (float) mVideoHeight;
- if (mVideoSarNum > 0 && mVideoSarDen > 0)
- displayAspectRatio = displayAspectRatio * mVideoSarNum / mVideoSarDen;
- break;
- }
- boolean shouldBeWider = displayAspectRatio > specAspectRatio;
- switch (mCurrentAspectRatio) {
- case IRenderView.AR_ASPECT_FIT_PARENT:
- case IRenderView.AR_16_9_FIT_PARENT:
- case IRenderView.AR_4_3_FIT_PARENT:
- if (shouldBeWider) {
- // too wide, fix width
- width = widthSpecSize;
- height = (int) (width / displayAspectRatio);
- } else {
- // too high, fix height
- height = heightSpecSize;
- width = (int) (height * displayAspectRatio);
- }
- break;
- case IRenderView.AR_ASPECT_FILL_PARENT:
- if (shouldBeWider) {
- // not high enough, fix height
- height = heightSpecSize;
- width = (int) (height * displayAspectRatio);
- } else {
- // not wide enough, fix width
- width = widthSpecSize;
- height = (int) (width / displayAspectRatio);
- }
- break;
- case IRenderView.AR_ASPECT_WRAP_CONTENT:
- default:
- if (shouldBeWider) {
- // too wide, fix width
- width = Math.min(mVideoWidth, widthSpecSize);
- height = (int) (width / displayAspectRatio);
- } else {
- // too high, fix height
- height = Math.min(mVideoHeight, heightSpecSize);
- width = (int) (height * displayAspectRatio);
- }
- break;
- }
- } else if (widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) {
- // the size is fixed
- width = widthSpecSize;
- height = heightSpecSize;
- // for compatibility, we adjust size based on aspect ratio
- if (mVideoWidth * height < width * mVideoHeight) {
- //Log.i("@@@", "image too wide, correcting");
- width = height * mVideoWidth / mVideoHeight;
- } else if (mVideoWidth * height > width * mVideoHeight) {
- //Log.i("@@@", "image too tall, correcting");
- height = width * mVideoHeight / mVideoWidth;
- }
- } else if (widthSpecMode == View.MeasureSpec.EXACTLY) {
- // only the width is fixed, adjust the height to match aspect ratio if possible
- width = widthSpecSize;
- height = width * mVideoHeight / mVideoWidth;
- if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
- // couldn't match aspect ratio within the constraints
- height = heightSpecSize;
- }
- } else if (heightSpecMode == View.MeasureSpec.EXACTLY) {
- // only the height is fixed, adjust the width to match aspect ratio if possible
- height = heightSpecSize;
- width = height * mVideoWidth / mVideoHeight;
- if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
- // couldn't match aspect ratio within the constraints
- width = widthSpecSize;
- }
- } else {
- // neither the width nor the height are fixed, try to use actual video size
- width = mVideoWidth;
- height = mVideoHeight;
- if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
- // too tall, decrease both width and height
- height = heightSpecSize;
- width = height * mVideoWidth / mVideoHeight;
- }
- if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
- // too wide, decrease both width and height
- width = widthSpecSize;
- height = width * mVideoHeight / mVideoWidth;
- }
- }
- } else {
- // no size yet, just adopt the given spec sizes
- }
- mMeasuredWidth = width;
- mMeasuredHeight = height;
- }
- public int getMeasuredWidth() {
- return mMeasuredWidth;
- }
- public int getMeasuredHeight() {
- return mMeasuredHeight;
- }
- public void setAspectRatio(int aspectRatio) {
- mCurrentAspectRatio = aspectRatio;
- }
- }
|