b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

十分钟完成安卓MediaCodec视频解码(2)

电脑杂谈  发布时间:2019-07-21 23:07:11  来源:网络整理

因为MediaCodec是硬解码,底层当然是用C语言实现的啦。

对于这种C语言实现的方法,用完了一定要记得回收!

        if (mediaCodec != null) {
            //停止解码,此时可以再次调用configure()方法
            mediaCodec.stop();
            //释放内存
            mediaCodec.release();
        }

完美解码安卓版_安卓版短信轰炸器_视频安卓版

但是需要注意在主线程中仅仅能设置线程状态,并不能真正停止当前线程,如果要终止线程必须程中调用exist方法,这是一个静态方法,调用该方法可以退出当前线程。调用view的dispatchdetachedfromwindow()方法, 内部会调用view的ondetachedfromwindow()以及ondetachedfromwindowinternal(). 而对于ondetachedfromwindow()就是在view从window中移除时, 这个方法就会被调用, 可以在这个方法内部做一些资源回收的工作. 比如停止,停止线程。 2、 “停止解码”后解码上墙停止,并且电视墙不会保留最后一帧图像(黑屏状态),如果未进行手动停止(例如网络中。

更改分辨率前必须调用stop!!!

完成解码之后,你会发现,MediaCodec这坑爹玩意儿居然默认是拉伸到满屏的,那么如果要保持屏幕纵横比怎么办?

MediaCodec自带了一个设置缩放模式的方法:


    //此方法必须在configure和start之后执行才有效
    mediaCodec.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
 

再次强调,这个方法必须在configure和start之后执行才有效!!!

调用这个方法之后,MediaCodec会把视频剪到满屏,对没错,剪到满屏。

在我们的网页布局中,经常需要用到div+css布局将图片水平左右居中、上下垂直居中显示,那该如何实现呢。搭配效果:中长宽松版型的军绿色毛呢外套搭配黑色打底裤最好不过了,穿上简约的t恤作打底,搭配百搭的黑色短靴,就能美美出街了。坎卦阳爻居中,上下各为阴爻,五行属水居北方,色黑。

然后通过修改layoutParams的方法来更改SurfaceView的大小,以此来达到保持纵横比又不被剪掉的情况下拉直满屏。

完美解码安卓版_安卓版短信轰炸器_视频安卓版

我已经在Stack Overflow上求证过,确实是只有这一个办法,硬着头皮上吧(代码量庞大注意!):

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/videoLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000"
    android:orientation="vertical">
    <SurfaceView
        android:id="@+id/videoSurfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />
</RelativeLayout>

代码:

//获取视频宽高以缩放渲染分辨率,注意此方法必须在releaseOutputBuffer之前执行
    public void fixHW() {
        if (width == 0 || height == 0) {
            width = videoLayout.getWidth();
            height = videoLayout.getHeight();
        }
        Log.e("tempWH", width + ":" + height);
        try {
            //获取视频格式信息,注意此方法必须在releaseOutputBuffer之前执行
            MediaFormat currentFormat = mediaCodec.getOutputFormat();
            mediaW = currentFormat.getInteger("width");
            mediaH = currentFormat.getInteger("height");
            Log.e("mediaWH", mediaW + ":" + mediaH);
            if (mediaH < height && mediaW < width) {
                Log.e("fixType", "mediaRes<layoutRes");
                height = mediaH;
                width = mediaW;
                doFix();
            } else if (mediaH >= height) {
                Log.e("fixType", "mediaH<layoutH");
                int fixW = mediaW * (height / mediaH);
                if (width != fixW) {
                    width = fixW;
                    doFix();
                }
            } else if (mediaW >= width) {
                Log.e("fixType", "mediaW<layoutW");
                int fixH = mediaH * (width / mediaW);
                if (height != fixH) {
                    height = fixH;
                    doFix();
                }
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }
    private void doFix() {
        Log.e("mediaWH", width + ":" + height);
        //应用新的渲染分辨率
        MediaFormat newFormat = MediaFormat.createVideoFormat(currentMIMEType, width, height);
        configureDecoder(newFormat, tempSurface);
        //运算videoSurfaceView的宽高以保持纵横比
        ViewGroup.LayoutParams surfaceLayoutParams = videoSurfaceView.getLayoutParams();
        surfaceLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        surfaceLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
        if (width > height) {
            int fixH = (int) (height * (videoLayout.getWidth() / (double) width));
            if (fixH < videoLayout.getHeight()) {
                surfaceLayoutParams.height = fixH;
            } else {
                surfaceLayoutParams.height = videoLayout.getHeight();
                surfaceLayoutParams.width = (int) (width * (surfaceLayoutParams.height / (double) height));
            }
            fixVideoLayout(surfaceLayoutParams);
        } else if (height > width) {
            int fixW = (int) (width * (videoLayout.getHeight() / (double) height));
            if (fixW < videoLayout.getWidth()) {
                surfaceLayoutParams.width = fixW;
            } else {
                surfaceLayoutParams.width = videoLayout.getWidth();
                surfaceLayoutParams.height = (int) (height * (surfaceLayoutParams.width / (double) width));
            }
            fixVideoLayout(surfaceLayoutParams);
        }
    }
    //应用videoSurfaceView的宽高,由于解码线程在子线程,这里需要切回主线程执行
    private void fixVideoLayout(ViewGroup.LayoutParams surfaceLayoutParams) {
        if (hdl_fixHWForSurfaceView == null) {
            hdl_fixHWForSurfaceView = new Handler(videoSurfaceView.getContext().getMainLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    videoSurfaceView.setLayoutParams((ViewGroup.LayoutParams) msg.obj);
                }
            };
        }
        Message msg = new Message();
        msg.obj = surfaceLayoutParams;
        hdl_fixHWForSurfaceView.sendMessage(msg);
        Log.e("layoutWH", surfaceLayoutParams.width + ":" + surfaceLayoutParams.height);
    }


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-114728-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...