uestccokey / EZFilter

A lightweight (<180KB), easy-to-extend Android filter and dynamic sticker framework for adding filters and stickers for camera, video, bitmap and view.(一个轻量级(<180KB)、易扩展的Android滤镜和动态贴纸框架,支持摄像头、视频、图片和视图添加滤镜和贴纸。)
MIT License
208 stars 57 forks source link

您好,请问下如何解决视频编解码绿边 #51

Closed chongbo2013 closed 5 years ago

chongbo2013 commented 5 years ago

现在分辨率是1080x2060 就会出现绿边,应该是编码器分辨率必须是 16 或者32 128倍数,请问如何比较好的解决方案

uestccokey commented 5 years ago

是特殊机型出现,还是都会出现?可以给我一个这种分辨率的测试视频吗?

chongbo2013 commented 5 years ago

是都会出现,我查看https://www.jianshu.com/p/ac53e9595940 他说有解决方案,我在想,老大是不是有更简单的解决方案 ,稍等我发送你视频 2.26视频模板(带字幕).zip

复现:解码播放视频,横屏播放就会出现绿边

chongbo2013 commented 5 years ago

还有部分机型出现crash Process: com.cgfay.caincamera, PID: 19445 android.media.MediaCodec$CodecException: Error 0xfffffc0e at android.media.MediaCodec.native_configure(Native Method) at android.media.MediaCodec.configure(MediaCodec.java:1967) at android.media.MediaCodec.configure(MediaCodec.java:1896) 度酿了下是因为传入放入宽高中高不是2的倍数,换言之,是个单数 https://blog.csdn.net/zhang___yong/article/details/82760756

uestccokey commented 5 years ago

我这边使用demo里的离屏渲染选择这个视频,渲染出来的视频没有绿边啊

uestccokey commented 5 years ago

crash我没遇到过,你按那个链接改了就没问题了么?

chongbo2013 commented 5 years ago

它可能跟 视频分辨率有关,得查看手机 宽高都是 16 位对齐,或 32 位、64 位、128 位, 然后撸个分辨率试试,

chongbo2013 commented 5 years ago

我还没改,我还在想要怎么改合适

uestccokey commented 5 years ago

你用demo里的离屏渲染选择这个视频,渲染出来是什么样的

chongbo2013 commented 5 years ago

我录屏你看看 录屏_20190410_120138.zip

uestccokey commented 5 years ago

好的,看到现象了,但是不知道你的处理逻辑,有关键代码吗?

uestccokey commented 5 years ago

最好能在我的demo里能复现

chongbo2013 commented 5 years ago

好的,我找时间复现下 哈在你demo

chongbo2013 commented 5 years ago

整到你demo里,不然比较难复现,谢谢哦

chongbo2013 commented 5 years ago

你好,还有个问题,大部分手机离屏渲染特别慢,有没有办法能解决

uestccokey commented 5 years ago

你是说帧率低,还是时间长

chongbo2013 commented 5 years ago

时间长

uestccokey commented 5 years ago

如果是时间太长,这个和你选的视频的时长有关系,电脑上处理视频也得等很久。 目前使用的GPU进行渲染,已经是最快速度,比FFMpeg等软解方式快了一个数量级。 最简单的解决办法是: 1.限制选择的视频长度,大部分App都会控制在15s内。 2.只在最后一步比如发送或者保存时再进行处理。 3.加上等待进度条

chongbo2013 commented 5 years ago

哦,有些手机特别慢

chongbo2013 commented 5 years ago

还有问题是 new Thread 无法中断,可以处理 突然推出 中断处理

uestccokey commented 5 years ago

哪儿的new Thread

chongbo2013 commented 5 years ago

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) { final List paths = Matisse.obtainPathResult(data); if (!paths.isEmpty()) { new Thread() { public void run() { final String output = "/sdcard/render.mp4";

// CropRender leftCropRender = new CropRender(); // leftCropRender.setCropRegion(new RectF(0, 0, 0.5f, 1)); // CropRender rightCropRender = new CropRender(); // rightCropRender.setCropRegion(new RectF(0.5f, 0, 1, 1)); // List cropRenders = new ArrayList<>(); // cropRenders.add(leftCropRender); // cropRenders.add(rightCropRender); // SplitInput splitInput = new HorizontalSplitInput(cropRenders); // OffscreenSplitVideo splitVideo = new OffscreenSplitVideo(paths.get(0), splitInput); // splitInput.getRenderPipelines().get(0).addFilterRender(new BWRender(VideoOffscreenActivity.this)); // try { // splitVideo.save(output); // } catch (IOException e) { // e.printStackTrace(); // } // // output是耗时操作,需要在异步线程调用 EZFilter.input(Uri.parse(paths.get(0))) .addFilter(new BWRender(VideoOffscreenActivity.this)) .addFilter(new WobbleRender()) .output(output);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            EZFilter.input(Uri.parse(output))
                                    .setLoop(true)
                                    .into(mRenderView);
                        }
                    });
                }
            }.start();
uestccokey commented 5 years ago

哦,demo里这个只是个最简单的例子,不用管

chongbo2013 commented 5 years ago

chongbo2013 commented 5 years ago

你好,现在出现 离屏渲染,二次编辑的时候,视频输出后是模糊的,如何解决

uestccokey commented 5 years ago

你看看,视频分辨率有没有改变,demo中是否能复现

chongbo2013 commented 5 years ago

可以的demo可以复现,就是,你用demo 录制一个视频,然后再用这个视频,去离屏一次,就发现离屏出的视频有马赛克和模糊了

chongbo2013 commented 5 years ago

这个视频,你离屏幕下,就模糊, render(4).zip

uestccokey commented 5 years ago

我试了下,感觉还好啊 render.mp4.zip

chongbo2013 commented 5 years ago

不会吧 哈哈,这么奇怪,那你再吧离屏的,继续离屏看看

uestccokey commented 5 years ago

我再次离屏渲染了一次,也没有马赛克啊,当然多次这样处理肯定就没法看了,因为滤镜效果叠加了。把你糊了的发给我看看是啥样的

chongbo2013 commented 5 years ago

我知道了,不同手机不一样。稍等哈,我发你个我渲染的

uestccokey commented 5 years ago

你看看OffscreenVideo里191行的bitrate,是多少,这个会影响视频质量,理论上视频宽高和比特率不出错的话,质量不会变

chongbo2013 commented 5 years ago

ok 谢谢大佬,大佬秒回,好人啊

chongbo2013 commented 5 years ago

大佬,后面支持视频,拼接吗

uestccokey commented 5 years ago

视频拼接可以用ffmpeg来做,比较方便

chongbo2013 commented 5 years ago

你好绿边我已经解决了,解码视频的时候,需要 ` MediaFormat outputFormat = mDecoder.getOutputFormat(); float left=0; float top=0; float right=1.0f; float bottom=1.0f; if(outputFormat!=null&&outputFormat.containsKey(MediaFormat.KEY_STRIDE)&&outputFormat.containsKey(MediaFormat.KEY_SLICE_HEIGHT)&&outputFormat.getInteger(MediaFormat.KEY_STRIDE)>0&&outputFormat.getInteger(MediaFormat.KEY_SLICE_HEIGHT)>0){ //576,1024 //原视频 //0,0,575,1023//裁剪区域 //640,1024//stride 宽高 float crop_top= outputFormat.getInteger("crop-top"); float crop_left= outputFormat.getInteger("crop-left"); float crop_right= outputFormat.getInteger("crop-right")+1; float crop_bottom= outputFormat.getInteger("crop-bottom")+1;

        float swidth=outputFormat.getInteger(MediaFormat.KEY_STRIDE);
        float sheiht=outputFormat.getInteger(MediaFormat.KEY_SLICE_HEIGHT);
        left=crop_top/swidth;
        top=crop_left/sheiht;
        right=crop_right/swidth;
        bottom=crop_bottom/sheiht;
    }
    cropRectF.set(left,1.0f-bottom,right,1.0f-top);`
uestccokey commented 5 years ago

👌

chongbo2013 commented 5 years ago

谢谢妲己,加个q哦,有空撸王者

yangkun19921001 commented 3 years ago

@chongbo2013 修复绿边问题,也可以根据你算出来的 right ,bottom 来缩放顶点坐标 ,经过测试也可以达到效果。

private float factor_w = 0.06f;
private float factor_h = 0.02f;

final float mVertices[] = {
        -1.0f, 1.0f,//左上角
        1.0f + factor_w, 1.0f,//右上角
        -1.0f, -1.0f - factor_h,//左下角
        1.0f + factor_w, -1.0f - factor_h //右下角
};
yzcslam commented 1 year ago

我也是用stride和sliceHeight去裁剪绿边,但是我发现有些机型在不裁剪的情况下存在绿边,然后获取MediaFormat中的stride和sliceHeight发现获取的值为0,就没办法裁剪了,而且很多机型都有这个问题,大佬们有碰到过这种问题吗?