Closed Shaooooo closed 2 months ago
Hello,
Your bitrate is really low for 1280720 resolution try with: 4000 1000 You have a guide of bitrate here: https://support.google.com/youtube/answer/2853702?hl=en
Hello,
Your bitrate is really low for 1280720 resolution try with: 4000 1000 You have a guide of bitrate here: https://support.google.com/youtube/answer/2853702?hl=en
Hi bro, thanks for your reply. I've tried to change the value of bitrate, the screen(1280720) still looks stutter and unstable, also create connection slowly. Is there any other way to make the video(1280720) playing smoothly?
There are two videos which is 1280720 and 640360 difference.
https://github.com/user-attachments/assets/0d1e1de3-0ac6-4541-8cc9-4bf40268fd35
https://github.com/user-attachments/assets/d0140fe2-4ea7-4f7c-9ef4-5d114f708791
Hello,
If you are using a SurfaceView, please replace it with a OpenGlView because SurfaceView performance is much worse than OpenGlView using camera1. The reason is that with SurfaceView the video frame are handled using CPU (I modify manually byte array from camera to rotate it) producing a low fps.
Hello,
If you are using a SurfaceView, please replace it with a OpenGlView because SurfaceView performance is much worse than OpenGlView using camera1. The reason is that with SurfaceView the video frame are handled using CPU (I modify manually byte array from camera to rotate it) producing a low fps.
Hello, I was using AutoFitTextureView.class. I'll try your suggestion. By the way , is there a wiki about OpenGlView?
I haven't a wiki. You only need use OpenGlView class in the XML adding this param to the XML view:
app:aspectRatioMode="adjust"
For example:
<com.pedro.library.view.OpenGlView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/surfaceView"
app:aspectRatioMode="adjust"
/>
In the Activity you need replace your surfaceTextureListener to (the code inside callbacks is the equivalent to the app example):
openglview.holder.addCallback(object: SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
if (!rtspServerCamera1.isOnPreview) {
rtspServerCamera1.startPreview()
adaptPreview()
}
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && rtspServerCamera1.isRecording) {
rtspServerCamera1.stopRecord()
bRecord.setBackgroundResource(R.drawable.record_icon)
PathUtils.updateGallery(this, recordPath)
}
if (rtspServerCamera1.isStreaming) {
rtspServerCamera1.stopStream()
bStream.setImageResource(R.drawable.stream_icon)
}
if (rtspServerCamera1.isOnPreview) rtspServerCamera1.stopPreview()
ScreenOrientation.unlockScreen(this)
}
})
I haven't a wiki. You only need use OpenGlView class in the XML adding this param to the XML view:
app:aspectRatioMode="adjust"
For example:
<com.pedro.library.view.OpenGlView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/surfaceView" app:aspectRatioMode="adjust" />
In the Activity you need replace your surfaceTextureListener to (the code inside callbacks is the equivalent to the app example):
openglview.holder.addCallback(object: SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) { } override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { if (!rtspServerCamera1.isOnPreview) { rtspServerCamera1.startPreview() adaptPreview() } } override fun surfaceDestroyed(holder: SurfaceHolder) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && rtspServerCamera1.isRecording) { rtspServerCamera1.stopRecord() bRecord.setBackgroundResource(R.drawable.record_icon) PathUtils.updateGallery(this, recordPath) } if (rtspServerCamera1.isStreaming) { rtspServerCamera1.stopStream() bStream.setImageResource(R.drawable.stream_icon) } if (rtspServerCamera1.isOnPreview) rtspServerCamera1.stopPreview() ScreenOrientation.unlockScreen(this) } })
Hello. First Thanks a lot, Now my OpenGlView and VLC client are all work good. Second there is a new problem. When I use OpenGlView, the code runs into the red rect. It makes the callback method public void onPreviewFrame(byte[] data, Camera camera) no response.
Why there is no set callback. If I add the code camera.setPreviewCallback(this); in the red rect. Is it allowed?
Hello,
You don't need a callback using OpenGlView because the VideoEncoder is using a surface to render video frames instead of use byte arrays. It is allowed but no recommended. You shouldn't use the callback because it is not needed (you are feeding VideoEncoder rendering a surface so send byte arrays is not needed). Also, you will need modify the library a bit to avoid send byte arrays to VideoEncoder and the CPU usage will be higher because you are working with that byte arrays.
Hello,
You don't need a callback using OpenGlView because the VideoEncoder is using a surface to render video frames instead of use byte arrays. It is allowed but no recommended. You shouldn't use the callback because it is not needed (you are feeding VideoEncoder rendering a surface so send byte arrays is not needed). Also, you will need modify the library a bit to avoid send byte arrays to VideoEncoder and the CPU usage will be higher because you are working with that byte arrays.
I got it. actually I really need the nv21 data from the camera frame callback to my APP logic, If I can't get it from onPreviewFrame, is there any other way get it?
You have other way but using camera2. The only problem is that your app need min API 21 (in most of cases it is not a problem). You only need replace RstpServerCamera1 to RstpServerCamera2. After that you can use this method to receive frames in yuv from the camera2:
//listen for yuv images. Call it any time after the preview is started
rstpServerCamera2.addImageListener(ImageFormat.YUV_420_888, 1) { image ->
//this must be without a thread because image class is released after this callback
val buffer = image.planes[0].buffer
val yuv = ByteArray(buffer.capacity())
buffer.get(yuv)
//recommended create a thread now and use the yuv byte array in that thread to avoid block this callback
}
//stop listen for yuv images
rstpServerCamera2.removeImageListener()
You have other way but using camera2. The only problem is that your app need min API 21 (in most of cases it is not a problem). You only need replace RstpServerCamera1 to RstpServerCamera2. After that you can use this method to receive frames in yuv from the camera2:
//listen for yuv images. Call it any time after the preview is started rstpServerCamera2.addImageListener(ImageFormat.YUV_420_888, 1) { image -> //this must be without a thread because image class is released after this callback val buffer = image.planes[0].buffer val yuv = ByteArray(buffer.capacity()) buffer.get(yuv) //recommended create a thread now and use the yuv byte array in that thread to avoid block this callback } //stop listen for yuv images rstpServerCamera2.removeImageListener()
Hello. Mr I've tried to use rstpServerCamera2 and OpenGlView. When I run App with them, the screen is black.
I'm sure that use camera1 and AutoFitTextureView was work good.
You have other way but using camera2. The only problem is that your app need min API 21 (in most of cases it is not a problem). You only need replace RstpServerCamera1 to RstpServerCamera2. After that you can use this method to receive frames in yuv from the camera2:
//listen for yuv images. Call it any time after the preview is started rstpServerCamera2.addImageListener(ImageFormat.YUV_420_888, 1) { image -> //this must be without a thread because image class is released after this callback val buffer = image.planes[0].buffer val yuv = ByteArray(buffer.capacity()) buffer.get(yuv) //recommended create a thread now and use the yuv byte array in that thread to avoid block this callback } //stop listen for yuv images rstpServerCamera2.removeImageListener()
Hello. Mr I've tried to use rstpServerCamera2 and OpenGlView. When I run App with them, the screen is black.
I'm sure that use camera1 and AutoFitTextureView was work good.
04-05 00:35:18.229 20062 20062 D gjx : CameraDemoActivity onCreate: ===========================================================================================
04-05 00:35:18.460 20062 20062 D gjx : surfaceCreated:
04-05 00:35:18.460 20062 20062 I CameraManagerGlobal: Connecting to camera service
04-05 00:35:18.465 353 12218 W ServiceManager: Permission failure: android.permission.CAMERA_OPEN_CLOSE_LISTENER from uid=10121 pid=20062
04-05 00:35:18.483 20062 20100 E SurfaceManager: GL already released
04-05 00:35:18.506 20062 20100 I SurfaceManager: GL initialized
04-05 00:35:18.516 268 726 D gps_ql : Error connecting rild-nmea (Connection refused)
04-05 00:35:18.516 268 726 D gps_ql : fail to open GPS channel
Hello,
Your code is not like in my example:
app:aspectRatioMode="adjust"
Hello,
Your code is not like in my example:
- Move the code from surfaceCreated to surfaceChanged callback
- Add this to xml OpenGlView:
app:aspectRatioMode="adjust"
- adaptPreview method is no longer necessary, remove it
It is the example of https://github.com/pedroSG94/RTSP-Server. follow your steps. the screen still black.
rtspServerCamera1.startPreview() happened an exception
04-05 01:11:07.730 20519 20519 D gjx : CameraDemoActivity onCreate: ===========================================================================================
04-05 01:11:07.744 313 396 W APM::AudioPolicyEngine: getDevicesForStrategy() unknown strategy: -1
04-05 01:11:07.744 444 27623 I system_server: oneway function results will be dropped but finished with status OK and parcel size 4
04-05 01:11:07.869 20519 20519 D gjx : surfaceCreated:
04-05 01:11:07.870 20519 20519 D gjx : surfaceChanged:
04-05 01:11:07.880 20519 20576 E SurfaceManager: GL already released
04-05 01:11:07.899 20519 20576 I SurfaceManager: GL initialized
04-05 01:11:07.912 20519 20576 E SurfaceManager: GL already released
04-05 01:11:07.931 20519 20576 I SurfaceManager: GL initialized
04-05 01:11:07.939 20519 20519 I Camera2ApiManager: optimal resolution set to: 640x480
04-05 01:11:07.944 20519 20519 E SurfaceView: Exception configuring surface
04-05 01:11:07.944 20519 20519 E SurfaceView: java.lang.IllegalArgumentException: cameraId was null
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:717)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:653)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.encoder.input.video.Camera2ApiManager.openCameraId(Camera2ApiManager.java:820)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.library.base.Camera2Base.startPreview(Camera2Base.java:528)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.library.base.Camera2Base.startPreview(Camera2Base.java:511)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.library.base.Camera2Base.startPreview(Camera2Base.java:545)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.library.base.Camera2Base.startPreview(Camera2Base.java:562)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.library.base.Camera2Base.startPreview(Camera2Base.java:571)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.pedro.sample.CameraDemoActivity$onCreate$1.surfaceChanged(CameraDemoActivity.kt:78)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.SurfaceView.updateSurface(SurfaceView.java:1165)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.SurfaceView.lambda$new$0$SurfaceView(SurfaceView.java:173)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.-$$Lambda$SurfaceView$w68OV7dB_zKVNsA-r0IrAUtyWas.onPreDraw(Unknown Source:2)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1093)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3094)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1948)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8177)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.Choreographer.doCallbacks(Choreographer.java:796)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.Choreographer.doFrame(Choreographer.java:731)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.os.Handler.handleCallback(Handler.java:938)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.os.Handler.dispatchMessage(Handler.java:99)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.os.Looper.loop(Looper.java:223)
04-05 01:11:07.944 20519 20519 E SurfaceView: at android.app.ActivityThread.main(ActivityThread.java:7664)
04-05 01:11:07.944 20519 20519 E SurfaceView: at java.lang.reflect.Method.invoke(Native Method)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
04-05 01:11:07.944 20519 20519 E SurfaceView: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
04-05 01:11:07.960 224 224 D gralloc4: [File] : hardware/rockchip/libgralloc/bifrost/src/hidl_common/Allocator.cpp; [Line] : 149; [Func] : allocate;
04-05 01:11:07.960 224 224 D gralloc4: got new private_handle_t instance @0xb400006f45629c30 for buffer 'com.pedro.sample/com.pedro.sample.CameraDemoActivity#0'. share_fd : 8, share_attr_fd : 9, flags : 0x4, width : 1280, height : 720, req_format : 0x1, producer_usage : 0x40000000000b00, consumer_usage : 0x40000000000b00, internal_format : 0x0, stride : 0, byte_stride : 0, internalWidth : 0, internalHeight : 0, alloc_format : 0x100000001, size : 3744768, layer_count : 1, backing_store_size : 3744768, backing_store_id : 962072677502, allocating_pid : 224, ref_count : 1, yuv_info : 0
04-05 01:11:07.960 224 224 D gralloc4: plane_info[0]: offset : 0, byte_stride : 5120, alloc_width : 1280, alloc_height : 720
04-05 01:11:07.960 224 224 D gralloc4: plane_info[1]: offset : 0, byte_stride : 0, alloc_width : 0, alloc_height : 0
04-05 01:11:07.990 444 471 I ActivityTaskManager: Displayed com.pedro.sample/.CameraDemoActivity: +480ms
04-05 01:11:08.037 224 224 D gralloc4: [File] : hardware/rockchip/libgralloc/bifrost/src/hidl_common/Allocator.cpp; [Line] : 149; [Func] : allocate;
04-05 01:11:08.037 224 224 D gralloc4: got new private_handle_t instance @0xb400006f45629b10 for buffer 'com.pedro.sample/com.pedro.sample.CameraDemoActivity#0'. share_fd : 8, share_attr_fd : 9, flags : 0x4, width : 1280, height : 720, req_format : 0x1, producer_usage : 0x40000000000b00, consumer_usage : 0x40000000000b00, internal_format : 0x0, stride : 0, byte_stride : 0, internalWidth : 0, internalHeight : 0, alloc_format : 0x100000001, size : 3744768, layer_count : 1, backing_store_size : 3744768, backing_store_id : 962072677503, allocating_pid : 224, ref_count : 1, yuv_info : 0
04-05 01:11:08.037 224 224 D gralloc4: plane_info[0]: offset : 0, byte_stride : 5120, alloc_width : 1280, alloc_height : 720
04-05 01:11:08.037 224 224 D gralloc4: plane_info[1]: offset : 0, byte_stride : 0, alloc_width : 0, alloc_height : 0
04-05 01:11:08.049 444 630 V WindowManager: getPackagePerformanceMode -- ComponentInfo{com.pedro.sample/com.pedro.sample.CameraDemoActivity} -- com.pedro.sample -- mode=0
04-05 01:11:08.126 268 726 D gps_ql : Error connecting rild-nmea (Connection refused)
04-05 01:11:08.126 268 726 D gps_ql : fail to open GPS channel
I tested using example from RTSP-Server and it is working fine. I did a branch for it: https://github.com/pedroSG94/RTSP-Server/pull/130
Test it and let me know the result. If the problem persist try with other device to discard problems with that phone
Closing as resolved here: https://github.com/pedroSG94/RTSP-Server/pull/130#issuecomment-2323431183
Use the last library version in the readme to get the fix
I try to use 1280720 in Camera1Base.class and prepareVideo(1280, 720, 20, 1200 1024, rotation). It could be displaying normal on android device screen. but I try to test the rtsp client by VLC media player. The screen was so bad in VLC.