mcchas / g2h-camera-mods

Modifying the G2H camera with rtsp, security and not to call home
MIT License
108 stars 14 forks source link

Increasing video bitrates #27

Open johndoewashere2 opened 2 years ago

johndoewashere2 commented 2 years ago

Hello,

Once again, thank you for the hard work so far.

I've been trying to find ways to increase both the streaming and recording bitrate from the camera as the video quality of rapidly moving subjects within the frames (e.g. foliage) tend to result in a hot mess, indicative of low video bitrate.

Below are my ventures so far:

Querying using getprop returns the following data with MaxBitrate highlighted:

[Video.0.H264VBR.ChangePos]: [80] 
[Video.0.H264VBR.Gop]: [40] 
[Video.0.H264VBR.IPQPDelta]: [0]
**[Video.0.H264VBR.MaxBitrate]: [2000000]**
[Video.0.H264VBR.MaxIQp]: [51]
[Video.0.H264VBR.MaxPQp]: [51]
[Video.0.H264VBR.MinIQp]: [10]
[Video.0.H264VBR.MinPQp]: [10]
[Video.0.H264VBR.StatTime]: [0]
[Video.0.RC.RcVersion]: [0]
[Video.0.RC.RowQpDelta]: [0]
[Video.0.RC.method]: [H264_VBR]
[Video.1.H264VBR.ChangePos]: [80]
[Video.1.H264VBR.Gop]: [40]
[Video.1.H264VBR.IPQPDelta]: [0]
**[Video.1.H264VBR.MaxBitrate]: [487192]**
[Video.1.H264VBR.MaxIQp]: [51]
[Video.1.H264VBR.MaxPQp]: [51]
[Video.1.H264VBR.MinIQp]: [10]
[Video.1.H264VBR.MinPQp]: [10]
[Video.1.H264VBR.StatTime]: [0]
[Video.1.RC.RcVersion]: [0]
[Video.1.RC.RowQpDelta]: [0]
[Video.1.RC.method]: [H264_VBR]
[Video.2.H264VBR.ChangePos]: [80]
[Video.2.H264VBR.Gop]: [40]
[Video.2.H264VBR.IPQPDelta]: [0]
**[Video.2.H264VBR.MaxBitrate]: [655360]**
[Video.2.H264VBR.MaxIQp]: [51]
[Video.2.H264VBR.MaxPQp]: [51]
[Video.2.H264VBR.MinIQp]: [10]
[Video.2.H264VBR.MinPQp]: [10]
[Video.2.H264VBR.StatTime]: [0]
[Video.2.RC.RcVersion]: [0]
[Video.2.RC.RowQpDelta]: [0]
[Video.2.RC.method]: [H264_VBR]

From what I can determine Video.0 stream is the main stream recorded to iCloud, Video.1 is the primary preview stream in Home app, couldn't figure out what Video.2 stream does but I have a hunch that it might be a secondary preview stream for a second user in the Home app.

The bitrate values appears to be in bytes based on saved footage retrieved from iCloud as they seem to hover around the 1.8Mbps region.

Trying to use the setprop command to change the respective MaxBitrate properties didn't quite work - setprop did indeed change the value, but upon starting a preview stream the values reverted again, the Video.1.H264VBR.MaxBitrate value did notably vary when the preview stream is active but it never seem to exceed 1046201 (just shy of 1Mbps).

Going through the /mnt/config/flash_config.ini file reveals two entries - bitrate0 and bitrate1 which by default is set to 0. The system seem to retain new values specified here (after figuring out that one has to remove the checksum = xxx line along with any blank spaces before running md5sum on the file) however it didn't seem to make any difference to the maximum video bitrate.

I then tried to grep the whole file system to look for the string 2000000 and found references in the camera log referring to bitrates set by the /tmp/out/camera binary.

As I'm not quite versed in inspecting data within binaries, any chance that you could please have a look @mcchas ?


On a side note, I've figured out how to set the time zone so the correct time appears when the time stamp is enabled (osd = 1).

The time zone appears to be specified in /etc/profile

After setting up the correct NTP server and confirming that the unit has the correct UTC time via the date -u command, I was able to determine that the default time zone data is set TZ=GMT-8 (for the EU unit I have) actually results in a GMT+8 time instead.

So setting the time involves changing the TZ= entry to your local time zone and invert the +/- prefix.

If you are located in a time zone with daylight savings, this would also help too:

As an alternative method to the specification of timezones using a pathname to a description file, SUSv3 describes the POSIX model. In this format, a string is defined as:

std offset [dst[offset][,start-date[/time],end-date[/time]]]
where std is the standard component name and dst is the daylight saving one. Each name consists of three or more characters. The offset is positive for timezones west of the prime meridian and negative for those east of the meridian. The offset is added to the local time to obtain UTC (formerly known as GMT). The start and end time fields indicate when the standard/daylight transitions occur.

For example, in the Eastern United States, standard time is 5-hours earlier than UTC, and we can specify EST5EDT in lieu of America/New_York. These alternatives are not always recognized, however, especially for zones outside of the United States and are best avoided.

HP-UX (an SUSv3 compliant UNIX) uses textual rules in /usr/lib/tztab and the POSIX names like EST5EDT, CST6CDT, MST7MDT, PST8PDT. The file includes all of the historical rules for each time zone, akin to the Olson database.

For someone residing in the Australian Central Standard/Daylight Time, the entry would be TZ=ACST-9:30ACDT

Reboot the unit after making the changes to see the updated changes.

mcchas commented 2 years ago

Good findings @johndoewashere2, quite happy to be experiencing daylight savings now 😄 . Tweaking other settings (like a lower GOP value - https://aws.amazon.com/blogs/media/part-1-back-to-basics-gops-explained/) might make for better quality video over bitrate alone. I have read that homekit secure video has certain limits (1080p but could be other limitations for fps and bitrates also). These video channels may also relate to the RTSP paths (/11, /12, /13 .etc) which could be used for testing.

You probably need to reboot for the program to take new config parameters (as restarting the camera program often trips the watchdog) and it looks like setprop is being used in an init script on startup, did you see these in /etc/init.d/S04mstar?

johndoewashere2 commented 2 years ago

You probably need to reboot for the program to take new config parameters (as restarting the camera program often trips the watchdog) and it looks like setprop is being used in an init script on startup, did you see these in /etc/init.d/S04mstar?

Had a look at the init.d script and it doesn't look like it influences any specific quality related settings. Additions to setprop other video quality values doesn't seem to be retained (check below).

The Video.n.xxxx values appears to be informational value despite being able to be modified using setprop - These values revert to the 'default' as soon as the video stream is started in the Home app.

Rebooting the unit didn't really make any difference with it retaining the settings in this case.

Removing the camera binary from /etc/normal.xml will allow the unit to power up without the camera binary:

        <process name="/tmp/out/camera">
                <arg desc="bring up by monitor">-M</arg>
        </process>

Interestingly getprop also returns less values configured:

# getprop
[init.svc.rcs]: [running]
[init.svc.ueventd]: [running]
[mi.debug.level]: [8]
[mi.sys.shrink_mem]: [1]
[mi.venc.bufcnt]: [2]
[mi.venc.sub.bufcnt]: [2]
[mi.vi.bufcnt]: [3]
[mi.vi.src]: [2]
[mi.vi.sub.bufcnt]: [2]
[mi.vi.sub.height]: [720]
[mi.vi.sub.width]: [1280]
[mstar.omx.gop.disable]: [1]
[mstar.omx.log.level]: [0]
[persist.sys.usb.config]: [adb]
[ro.allow.mock.location]: [0]
[ro.baseband]: [unknown]
[ro.bootloader]: [unknown]
[ro.bootmode]: [unknown]
[ro.debuggable]: [1]
[ro.factorytest]: [0]
[ro.hardware]: [mstarinfinity3(flatteneddevicet]
[ro.revision]: [0]
[ro.secure]: [1]
[ro.serialno]: []
[ro.system_rcs]: [1]

Starting the camera binary manually via the command `/tmp/out/camera -M' shows an interesting section of logs when camera preview is started in the Home app:

20211012 20:36:03.584 NOTICE   camera_tmp 542: homekit start recording
20211012 20:36:03.586 NOTICE   camera_tmp 564: report motiondetection[0]
20211012 20:36:03.586 ERROR    camera_tmp 2563: gateway session uninit
20211012 20:36:09.705 NOTICE   camera_tmp 1237: snapshot width: 1280, height 720
2021-10-12'T'10:06:10'Z'    Default [com.apple.mfi.HomeKit.Core:RequestHandlers] Completing Setup Endpoints transaction.
20211012 20:36:11.011 NOTICE   camera_tmp 1021: req: {"ch":1,"width":1280,"height":720}
20211012 20:36:11.014 NOTICE   camera_tmp 1056: same resolution: 1_1280_720
20211012 20:36:11.024 NOTICE   camera_tmp 998: set bitrate: 1_299000
20211012 20:36:11.034 NOTICE   camera_tmp 953: set framerate: 1_30
20211012 20:36:11.035 WARN     camera_tmp 620: framerate overflow[30], set to max framerate: 20
20211012 20:36:11.036 NOTICE   camera_tmp 625: hal set framerate: 20_20
20211012 20:36:11.040 NOTICE   camera_tmp 85: asc[0_4]: 0xf8
20211012 20:36:11.041 NOTICE   camera_tmp 85: asc[1_4]: 0xf0
20211012 20:36:11.042 NOTICE   camera_tmp 85: asc[2_4]: 0x30
20211012 20:36:11.043 NOTICE   camera_tmp 85: asc[3_4]: 0x0
20211012 20:36:11.043 NOTICE   camera_tmp 85: asc[3_4]: 0x0
20211012 20:36:11.053 NOTICE   camera_tmp 214: force read idr
20211012 20:36:11.496 NOTICE   camera_tmp 998: set bitrate: 1_290180
20211012 20:36:13.497 NOTICE   camera_tmp 998: set bitrate: 1_344529
20211012 20:36:13.996 NOTICE   camera_tmp 998: set bitrate: 1_409552
20211012 20:36:14.497 NOTICE   camera_tmp 998: set bitrate: 1_487192
20211012 20:36:14.996 NOTICE   camera_tmp 998: set bitrate: 1_579390
20211012 20:36:15.497 NOTICE   camera_tmp 998: set bitrate: 1_671588
20211012 20:36:15.996 NOTICE   camera_tmp 998: set bitrate: 1_778343
20211012 20:36:16.497 NOTICE   camera_tmp 998: set bitrate: 1_902567
20211012 20:36:17.002 NOTICE   camera_tmp 998: set bitrate: 1_1046201
20211012 20:36:21.246 NOTICE   camera_tmp 115: No recording configuration selected.

Quitting the camera process and re-running getprop confirms my suspicion, any custom values appears to be overridden by the camera process.

# getprop
[Video.0.H264VBR.ChangePos]: [80]
[Video.0.H264VBR.Gop]: [40]
[Video.0.H264VBR.IPQPDelta]: [0]
[Video.0.H264VBR.MaxBitrate]: [1048576]
[Video.0.H264VBR.MaxIQp]: [51]
[Video.0.H264VBR.MaxPQp]: [51]
[Video.0.H264VBR.MinIQp]: [10]
[Video.0.H264VBR.MinPQp]: [10]
[Video.0.H264VBR.StatTime]: [0]
[Video.0.RC.RcVersion]: [0]
[Video.0.RC.RowQpDelta]: [0]
[Video.0.RC.method]: [H264_VBR]
[Video.1.H264VBR.ChangePos]: [80]
[Video.1.H264VBR.Gop]: [40]
[Video.1.H264VBR.IPQPDelta]: [0]
[Video.1.H264VBR.MaxBitrate]: [1046201]
[Video.1.H264VBR.MaxIQp]: [51]
[Video.1.H264VBR.MaxPQp]: [51]
[Video.1.H264VBR.MinIQp]: [10]
[Video.1.H264VBR.MinPQp]: [10]
[Video.1.H264VBR.StatTime]: [0]
[Video.1.RC.RcVersion]: [0]
[Video.1.RC.RowQpDelta]: [0]
[Video.1.RC.method]: [H264_VBR]
[Video.2.H264VBR.ChangePos]: [80]
[Video.2.H264VBR.Gop]: [40]
[Video.2.H264VBR.IPQPDelta]: [0]
[Video.2.H264VBR.MaxBitrate]: [655360]
[Video.2.H264VBR.MaxIQp]: [51]
[Video.2.H264VBR.MaxPQp]: [51]
[Video.2.H264VBR.MinIQp]: [10]
[Video.2.H264VBR.MinPQp]: [10]
[Video.2.H264VBR.StatTime]: [0]
[Video.2.RC.RcVersion]: [0]
[Video.2.RC.RowQpDelta]: [0]
[Video.2.RC.method]: [H264_VBR]
[init.svc.rcs]: [running]
[init.svc.ueventd]: [running]
[mi.debug.level]: [8]
[mi.debug.proc.ADEC.ready]: [1]
[mi.debug.proc.AENC.ready]: [1]
[mi.debug.proc.AI.ready]: [1]
[mi.debug.proc.AO.ready]: [1]
[mi.debug.proc.MI.ready]: [1]
[mi.debug.proc.OSD.ready]: [1]
[mi.debug.proc.VENC.ready]: [1]
[mi.debug.proc.VI.ready]: [1]
[mi.sys.shrink_mem]: [1]
[mi.venc.bufcnt]: [2]
[mi.venc.sub.bufcnt]: [2]
[mi.vi.bufcnt]: [3]
[mi.vi.src]: [2]
[mi.vi.sub.bufcnt]: [2]
[mi.vi.sub.height]: [720]
[mi.vi.sub.width]: [1280]
[mstar.omx.gop.disable]: [1]
[mstar.omx.log.level]: [0]
[persist.sys.usb.config]: [adb]
[ro.allow.mock.location]: [0]
[ro.baseband]: [unknown]
[ro.bootloader]: [unknown]
[ro.bootmode]: [unknown]
[ro.debuggable]: [1]
[ro.factorytest]: [0]
[ro.hardware]: [mstarinfinity3(flatteneddevicet]
[ro.revision]: [0]
[ro.secure]: [1]
[ro.serialno]: []
[ro.system_rcs]: [1]
sdugoten commented 10 months ago

You probably need to reboot for the program to take new config parameters (as restarting the camera program often trips the watchdog) and it looks like setprop is being used in an init script on startup, did you see these in /etc/init.d/S04mstar?

Had a look at the init.d script and it doesn't look like it influences any specific quality related settings. Additions to setprop other video quality values doesn't seem to be retained (check below).

The Video.n.xxxx values appears to be informational value despite being able to be modified using setprop - These values revert to the 'default' as soon as the video stream is started in the Home app.

Rebooting the unit didn't really make any difference with it retaining the settings in this case.

Removing the camera binary from /etc/normal.xml will allow the unit to power up without the camera binary:

        <process name="/tmp/out/camera">
                <arg desc="bring up by monitor">-M</arg>
        </process>

Interestingly getprop also returns less values configured:

# getprop
[init.svc.rcs]: [running]
[init.svc.ueventd]: [running]
[mi.debug.level]: [8]
[mi.sys.shrink_mem]: [1]
[mi.venc.bufcnt]: [2]
[mi.venc.sub.bufcnt]: [2]
[mi.vi.bufcnt]: [3]
[mi.vi.src]: [2]
[mi.vi.sub.bufcnt]: [2]
[mi.vi.sub.height]: [720]
[mi.vi.sub.width]: [1280]
[mstar.omx.gop.disable]: [1]
[mstar.omx.log.level]: [0]
[persist.sys.usb.config]: [adb]
[ro.allow.mock.location]: [0]
[ro.baseband]: [unknown]
[ro.bootloader]: [unknown]
[ro.bootmode]: [unknown]
[ro.debuggable]: [1]
[ro.factorytest]: [0]
[ro.hardware]: [mstarinfinity3(flatteneddevicet]
[ro.revision]: [0]
[ro.secure]: [1]
[ro.serialno]: []
[ro.system_rcs]: [1]

Starting the camera binary manually via the command `/tmp/out/camera -M' shows an interesting section of logs when camera preview is started in the Home app:

20211012 20:36:03.584 NOTICE   camera_tmp 542: homekit start recording
20211012 20:36:03.586 NOTICE   camera_tmp 564: report motiondetection[0]
20211012 20:36:03.586 ERROR    camera_tmp 2563: gateway session uninit
20211012 20:36:09.705 NOTICE   camera_tmp 1237: snapshot width: 1280, height 720
2021-10-12'T'10:06:10'Z'    Default [com.apple.mfi.HomeKit.Core:RequestHandlers] Completing Setup Endpoints transaction.
20211012 20:36:11.011 NOTICE   camera_tmp 1021: req: {"ch":1,"width":1280,"height":720}
20211012 20:36:11.014 NOTICE   camera_tmp 1056: same resolution: 1_1280_720
20211012 20:36:11.024 NOTICE   camera_tmp 998: set bitrate: 1_299000
20211012 20:36:11.034 NOTICE   camera_tmp 953: set framerate: 1_30
20211012 20:36:11.035 WARN     camera_tmp 620: framerate overflow[30], set to max framerate: 20
20211012 20:36:11.036 NOTICE   camera_tmp 625: hal set framerate: 20_20
20211012 20:36:11.040 NOTICE   camera_tmp 85: asc[0_4]: 0xf8
20211012 20:36:11.041 NOTICE   camera_tmp 85: asc[1_4]: 0xf0
20211012 20:36:11.042 NOTICE   camera_tmp 85: asc[2_4]: 0x30
20211012 20:36:11.043 NOTICE   camera_tmp 85: asc[3_4]: 0x0
20211012 20:36:11.043 NOTICE   camera_tmp 85: asc[3_4]: 0x0
20211012 20:36:11.053 NOTICE   camera_tmp 214: force read idr
20211012 20:36:11.496 NOTICE   camera_tmp 998: set bitrate: 1_290180
20211012 20:36:13.497 NOTICE   camera_tmp 998: set bitrate: 1_344529
20211012 20:36:13.996 NOTICE   camera_tmp 998: set bitrate: 1_409552
20211012 20:36:14.497 NOTICE   camera_tmp 998: set bitrate: 1_487192
20211012 20:36:14.996 NOTICE   camera_tmp 998: set bitrate: 1_579390
20211012 20:36:15.497 NOTICE   camera_tmp 998: set bitrate: 1_671588
20211012 20:36:15.996 NOTICE   camera_tmp 998: set bitrate: 1_778343
20211012 20:36:16.497 NOTICE   camera_tmp 998: set bitrate: 1_902567
20211012 20:36:17.002 NOTICE   camera_tmp 998: set bitrate: 1_1046201
20211012 20:36:21.246 NOTICE   camera_tmp 115: No recording configuration selected.

Quitting the camera process and re-running getprop confirms my suspicion, any custom values appears to be overridden by the camera process.

# getprop
[Video.0.H264VBR.ChangePos]: [80]
[Video.0.H264VBR.Gop]: [40]
[Video.0.H264VBR.IPQPDelta]: [0]
[Video.0.H264VBR.MaxBitrate]: [1048576]
[Video.0.H264VBR.MaxIQp]: [51]
[Video.0.H264VBR.MaxPQp]: [51]
[Video.0.H264VBR.MinIQp]: [10]
[Video.0.H264VBR.MinPQp]: [10]
[Video.0.H264VBR.StatTime]: [0]
[Video.0.RC.RcVersion]: [0]
[Video.0.RC.RowQpDelta]: [0]
[Video.0.RC.method]: [H264_VBR]
[Video.1.H264VBR.ChangePos]: [80]
[Video.1.H264VBR.Gop]: [40]
[Video.1.H264VBR.IPQPDelta]: [0]
[Video.1.H264VBR.MaxBitrate]: [1046201]
[Video.1.H264VBR.MaxIQp]: [51]
[Video.1.H264VBR.MaxPQp]: [51]
[Video.1.H264VBR.MinIQp]: [10]
[Video.1.H264VBR.MinPQp]: [10]
[Video.1.H264VBR.StatTime]: [0]
[Video.1.RC.RcVersion]: [0]
[Video.1.RC.RowQpDelta]: [0]
[Video.1.RC.method]: [H264_VBR]
[Video.2.H264VBR.ChangePos]: [80]
[Video.2.H264VBR.Gop]: [40]
[Video.2.H264VBR.IPQPDelta]: [0]
[Video.2.H264VBR.MaxBitrate]: [655360]
[Video.2.H264VBR.MaxIQp]: [51]
[Video.2.H264VBR.MaxPQp]: [51]
[Video.2.H264VBR.MinIQp]: [10]
[Video.2.H264VBR.MinPQp]: [10]
[Video.2.H264VBR.StatTime]: [0]
[Video.2.RC.RcVersion]: [0]
[Video.2.RC.RowQpDelta]: [0]
[Video.2.RC.method]: [H264_VBR]
[init.svc.rcs]: [running]
[init.svc.ueventd]: [running]
[mi.debug.level]: [8]
[mi.debug.proc.ADEC.ready]: [1]
[mi.debug.proc.AENC.ready]: [1]
[mi.debug.proc.AI.ready]: [1]
[mi.debug.proc.AO.ready]: [1]
[mi.debug.proc.MI.ready]: [1]
[mi.debug.proc.OSD.ready]: [1]
[mi.debug.proc.VENC.ready]: [1]
[mi.debug.proc.VI.ready]: [1]
[mi.sys.shrink_mem]: [1]
[mi.venc.bufcnt]: [2]
[mi.venc.sub.bufcnt]: [2]
[mi.vi.bufcnt]: [3]
[mi.vi.src]: [2]
[mi.vi.sub.bufcnt]: [2]
[mi.vi.sub.height]: [720]
[mi.vi.sub.width]: [1280]
[mstar.omx.gop.disable]: [1]
[mstar.omx.log.level]: [0]
[persist.sys.usb.config]: [adb]
[ro.allow.mock.location]: [0]
[ro.baseband]: [unknown]
[ro.bootloader]: [unknown]
[ro.bootmode]: [unknown]
[ro.debuggable]: [1]
[ro.factorytest]: [0]
[ro.hardware]: [mstarinfinity3(flatteneddevicet]
[ro.revision]: [0]
[ro.secure]: [1]
[ro.serialno]: []
[ro.system_rcs]: [1]

@mcchas @johndoewashere2

wonder if you eventually find out how to fix the tearing image on moving object in the video? I found that is not in a usable state because any moving object will have big tearing screen.

BTW, what is the proper URL for the static image?

I have setting something like this

image

mcchas commented 10 months ago

@mcchas @johndoewashere2

wonder if you eventually find out how to fix the tearing image on moving object in the video? I found that is not in a usable state because any moving object will have big tearing screen.

BTW, what is the proper URL for the static image?

I have setting something like this

I have not noticed any tearing images when objects were moving. However mine don't often see much movement.

The issue could be related to the stream quality (the wifi module in these devices is not great) as it would be an adaptive bitrate. It could also be your player. You can check that your device is connecting at a decent wifi speed - sometimes mine fall back to 1-2mbps. You could also try using something like ffplay and testing the different streams (other than 15).

Not sure of a static image URL - don't recall seeing one available.

sdugoten commented 10 months ago

@mcchas @johndoewashere2 wonder if you eventually find out how to fix the tearing image on moving object in the video? I found that is not in a usable state because any moving object will have big tearing screen. BTW, what is the proper URL for the static image? I have setting something like this

I have not noticed any tearing images when objects were moving. However mine don't often see much movement.

The issue could be related to the stream quality (the wifi module in these devices is not great) as it would be an adaptive bitrate. It could also be your player. You can check that your device is connecting at a decent wifi speed - sometimes mine fall back to 1-2mbps. You could also try using something like ffplay and testing the different streams (other than 15).

Not sure of a static image URL - don't recall seeing one available.

I literally place the G2H right next to the wifi router when I was testing...so i am pretty sure it's not a wifi issue. I might test out some other value instead of 15.

Here is the picture when I was just raising my arm next to my desk...

image

If I change to something other than 15, do I have to restart home assistant or restart the G2H? Thanks.

mcchas commented 10 months ago

If I change to something other than 15, do I have to restart home assistant or restart the G2H? Thanks.

You won't need to reboot, the urls are all available.

That image is very bad. I've never experienced anything like this on G2H. If it's not the network connection it may be your player. If it's HA on a rpi or other low powered device it may be overloaded. For the RPi and other cameras I have had to use the onboard hardware h264 decoder in order to get stable quality in the past. You could check the cpu load of your machine during playback to rule that out. Looks overly compressed, but I suspect it's not the camera!