pedroSG94 / RootEncoder

RootEncoder for Android (rtmp-rtsp-stream-client-java) is a stream encoder to push video/audio to media servers using protocols RTMP, RTSP, SRT and UDP with all code written in Java/Kotlin
Apache License 2.0
2.52k stars 768 forks source link

cannot set bitrate in displayBase to increase the video quality #1377

Open alexso0121 opened 8 months ago

alexso0121 commented 8 months ago

Hello I am trying to work on the screen mirroring following the display example in demo.But I found that the resolution is quite poor when it displays the data in the rtmp player. I have tried to setBitrate by using the prepareVideo function in the displayBase.But I just found that the bitrate cannot be changed.

Here is my error log:

3 encoders found
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Encoder OMX.sprd.h264.encoder
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Color supported: 2135033992
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Color supported: 2144337921
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Color supported: 21
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Color supported: 19
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Color supported: 2130708361
2024-01-08 14:01:54.490 22842-22842 VideoEncoder            com.example.teacherpad               I  Encoder selected OMX.sprd.h264.encoder
2024-01-08 14:01:54.497 22842-22842 VideoEncoder            com.example.teacherpad               I  Prepare video info: SURFACE, 640x480
2024-01-08 14:01:54.497 22842-22842 VideoEncoder            com.example.teacherpad               I  bitrate mode CBR not supported using default mode
2024-01-08 14:01:54.503 22842-23192 ACodec                  com.example.teacherpad               I  setupVideoEncoder succeeded
2024-01-08 14:01:54.506 22842-22842 VideoEncoder            com.example.teacherpad               I  prepared

my prepare function for reference:

        keepAliveTrick()
        stopStream()
        if (endpoint.startsWith("rtmp")) {
            displayBase = RtmpDisplay(baseContext, true, connectChecker)
//            displayBase?.setVideoBitrateOnFly(1920*1080*30)
            displayBase?.setIntentResult(resultCode, data)

        } else {
            displayBase = RtmpDisplay(baseContext, true, connectChecker)
            displayBase?.setIntentResult(resultCode, data)
        }
        displayBase?.glInterface?.setForceRender(true)
        val width:Double=video_config_map["width"]!! as Double
        val height:Double=video_config_map["height"]!! as Double

        Log.d("mytag", "width=$width")
        Log.d("mytag", "height=$height")

        val prepareVideo=displayBase?.prepareVideo(width.toInt(),height.toInt(), video_config_map["fps"]!! as Int, 35000, 0, 320)
//        displayBase?.setVideoCodec(VideoCodec.H265)
        Log.d("mytag", prepareVideo.toString())
    }

and the rest of the code should the same as the example

the VideoEncoder has used default bitrate since my inputed bitrate is not supported by CBR.But I have already tried different bitrate like 800000, 500000, or even the default one 1200*1024, all of them has the same error.So I am wondering what is the correct bitrate I should tried to increase my video resolution

pedroSG94 commented 8 months ago

Hello,

Video resolution is set using width and height parameters so I Think that you mean video quality. In this case Display is a bit special because you need set dpi parameter depend of your screen device. You can get max dpi of your screen using this method:

getResources().getDisplayMetrics().densityDpi

This should give you the max dpi for your device and this will increase the quality. You can read more about it in this post: https://stackoverflow.com/questions/3166501/getting-the-screen-density-programmatically-in-android

alexso0121 commented 8 months ago

I have try something like this :

 fun prepareStreamRtp(endpoint: String, resultCode: Int, data: Intent,video_config_map: HashMap<String, Any>) {
        keepAliveTrick()
        stopStream()
        if (endpoint.startsWith("rtmp")) {
            displayBase = RtmpDisplay(baseContext, true, connectChecker)
//            displayBase?.setVideoBitrateOnFly(1920*1080*30)
            displayBase?.setIntentResult(resultCode, data)

        } else {
            displayBase = RtspDisplay(baseContext, true, connectChecker)
            displayBase?.setIntentResult(resultCode, data)
        }

        val width:Double = video_config_map["width"] as Double
        val height:Double = video_config_map["height"] as Double
        displayBase?.glInterface?.setForceRender(true)
        var maxdpi=getResources().getDisplayMetrics().densityDpi

//        displayBase?.prepareVideo(width.toInt(), height.toInt(), video_config_map["fps"]!! as Int, video_config_map["bitrate"]!! as Int, 0, 320)
        displayBase?.prepareVideo(width.toInt(), height.toInt(), 30,186624000, 0,maxdpi)

    }

    @RequiresApi(api = 29)
    fun startStreamRtp(endpoint: String) {
        if (displayBase?.isStreaming != true) {
//            if (displayBase?.prepareVideo() == true && displayBase?.prepareAudio() == true) {
//                displayBase?.startStream(endpoint)
//            }
            if (displayBase?.prepareVideo() == true && displayBase?.prepareInternalAudio() == true) {
                val bitrate = displayBase?.bitrate
                Log.i("mytag", "bitrate = $bitrate")
                val resolutionValue = displayBase?.resolutionValue
                Log.i("mytag", "resolutionValue = $resolutionValue")
                displayBase?.startStream(endpoint)
            }
        } else {
            showNotification("You are already streaming :(")
        }
    }

But Unfortunately, the quality and resolution of the video is still poor

pedroSG94 commented 8 months ago

Hello,

I'm not sure the way you are using the methods but you have 2 prepareVideo methods so you should use the same configuration in both cases. I mean this line:

            if (displayBase?.prepareVideo() == true && displayBase?.prepareInternalAudio() == true) {

prepareVideo without parameters is like use this: https://github.com/pedroSG94/RootEncoder/blob/master/library/src/main/java/com/pedro/library/base/DisplayBase.java#L275

So you should use parameters like in the first case that you use prepareVideo

alexso0121 commented 8 months ago

Thank you so much for your help. I have a much better video quality now.