yi-hack-v5 icon indicating copy to clipboard operation
yi-hack-v5 copied to clipboard

h264grabber on old 720p 21CN

Open roger- opened this issue 2 years ago • 41 comments

Sorry for posting about an unsupported device, but I'm trying to get h264grabber (and later rRTSPServer, etc.) running on an old 21CN Yi Ants 720p cam (Hi3518E V100). Currently it runs the original yi-hack.

The h264grabber binary from yi-hack-v5 seems to run okay, but the view file is in /home/jrview/view so I had to symlink it to /tmp/view. Running now gives me:

# ./h264grabber -m yi-home -d > /dev/null
Debug on
Resolution high
1654179172432 - mapping file /tmp/view, size 1586752, to 400d1000
1654179172455 - closing the file /tmp/view
1654179172458 - found latest frame: id -1, frame_counter 40759
1654179172461 - processing frame -1
1654179172483 - processing frame -1
1654179172504 - processing frame -1
1654179172523 - processing frame -1

I suspect the offsets in h264grabber.c aren't appropriate for my device/firmware. Also my view file is 3110752 bytes, which I think is larger than other devices.

How do I determine the correct offsets? I saw @roleoroleo had helped someone in this thread but I don't think the procedure was explained.

Appreciate any help!

EDIT: running the following:

 ln -s /home/jrview/view /tmp/view
 ./h264grabber -m yi_home --buf_size=3110752 -d -f &
./rRTSPServer

Gives me some distorted RTSP output in VLC, which eventually stops. Seems like it should work if I get the offsets right.

Using h264-bitstream-viewer and a hex editor my best guesses so far are:

table_record_num = 150
table_offset_high = 0x10
table_offset_low = 0x00003FE0
stream_offset_high = 0x0001779C
stream_offset_low = 0x0021779C 
buf_size = 3110752 

With everything else the same as yi_home.

This doesn't work unfortunately.

roger- avatar Jun 02 '22 15:06 roger-

I think your params are as follow:

#define TABLE_HIGH_OFFSET 0x10
#define TABLE_LOW_OFFSET 0x3FE0
#define TABLE_RECORD_SIZE 32
#define TABLE_RECORD_NUM 500
#define BUF_SIZE 3110752
#define STREAM_HIGH_OFFSET 0x177A0
#define STREAM_LOW_OFFSET 0x2177A0
#define FRAME_COUNTER_OFFSET 18
#define FRAME_OFFSET_OFFSET 4
#define FRAME_LENGTH_OFFSET 8

But I need 2-3 copies of the file to check it. Copy the file, wait 4 seconds, make another copy, wait 4 seconds, etc...

roleoroleo avatar Jun 03 '22 17:06 roleoroleo

Thanks, tried that and got this:

#./h264grabber -m yi_home -r HIGH -d -f --buf_size 3110752 --table_record_num 500 --stream_offset 96160 --table_offset 16
Debug on
Using fifo as output
Resolution high
1654278690409 - mapping file /tmp/view, size 3110752, to 40264000
1654278690414 - closing the file /tmp/view
1654278704586 - found latest frame: id 202, frame_counter 33657
1654278704591 - processing frame 202
1654278704616 - processing frame 202
1654278704636 - processing frame 202
1654278704657 - processing frame 202
1654278704679 - processing frame 202
1654278704679 - writing frame: frame_offset 1955956, frame_ptr 40459014, frame_length 331
1654278704697 - processing frame 203
1654278704717 - processing frame 203
1654278704717 - writing frame: frame_offset 1956352, frame_ptr 404591a0, frame_length 370
1654278704737 - processing frame 204
1654278704757 - processing frame 204
1654278704779 - processing frame 204
1654278704782 - writing frame: frame_offset 1956788, frame_ptr 40459354, frame_length 354
1654278704807 - processing frame 205
1654278704828 - processing frame 205
1654278704828 - writing frame: frame_offset 1957208, frame_ptr 404594f8, frame_length 408
1654278704847 - processing frame 206
1654278704867 - processing frame 206
1654278704867 - writing frame: frame_offset 1957680, frame_ptr 404596d0, frame_length 330
1654278704888 - processing frame 207
1654278704907 - processing frame 207
1654278704929 - processing frame 207
1654278704929 - writing frame: frame_offset 1958076, frame_ptr 4045985c, frame_length 375
1654278704947 - processing frame 208
1654278704967 - processing frame 208

VLC doesn't load anything though.

BTW in my recent digging I thought table_record_num=450 and table_offset_low=0x00003860.

Here are three examples, appreciate your help!

roger- avatar Jun 03 '22 17:06 roger-

Try these:

#define TABLE_HIGH_OFFSET 0x10
#define TABLE_LOW_OFFSET 0x3EA0
#define TABLE_RECORD_SIZE 32
#define TABLE_RECORD_NUM 500
#define BUF_SIZE 3110752
#define STREAM_HIGH_OFFSET 0x17760
#define STREAM_LOW_OFFSET 0x217760
#define FRAME_COUNTER_OFFSET 18
#define FRAME_OFFSET_OFFSET 4
#define FRAME_LENGTH_OFFSET 8

roleoroleo avatar Jun 03 '22 19:06 roleoroleo

That works, thanks! Things are in black and white, but I suspect there's an IR-cut filter issue.

FYI tested low with:

./h264grabber -m yi_home -r HIGH -d -f  --buf_size 3110752 --table_record_num 500 --stream_offset 2193248 --table_offset 16032

and high with:

/h264grabber -m yi_home -r HIGH -d -f  --buf_size 3110752 --table_record_num 500 --stream_offset 96096

I do see some weird output messages like this:

1654287718106 - processing frame 492
1654287718107 - writing frame: frame_offset 534644, frame_ptr 4035bfd4, frame_length 2842
1654287718126 - processing frame 493
1654287718147 - processing frame 493
1654287718147 - writing frame: frame_offset 537552, frame_ptr 4035cb30, frame_length 3574
1654287718166 - processing frame 494
1654287718166 - writing frame: frame_offset 541192, frame_ptr 4035d968, frame_length 15
1654287718186 - processing frame 495
1654287718189 - writing frame: frame_offset 541272, frame_ptr 4035d9b8, frame_length 8
1654287718216 - processing frame 496
1654287718216 - writing frame: frame_offset 541344, frame_ptr 4035da00, frame_length 17179
1654287718236 - processing frame 497
1654287718256 - processing frame 497
1654287718276 - processing frame 497
1654287718277 - writing frame: frame_offset 558588, frame_ptr 40361d5c, frame_length 3557
1654287718296 - processing frame 498
1654287718316 - processing frame 498
1654287718316 - writing frame: frame_offset 562212, frame_ptr 40362b84, frame_length 6602
1654287718336 - processing frame 499
1654287718336 - rewinding circular table
1654287718356 - processing frame 499
1654287718356 - rewinding circular table
1654287718376 - processing frame 499
1654287718376 - rewinding circular table
1654287718376 - writing frame: frame_offset 568880, frame_ptr 40364590, frame_length 3693
1654287718405 - processing frame 0
1654287718426 - processing frame 0
1654287718426 - writing frame: frame_offset 572640, frame_ptr 40365440, frame_length 3538
1654287718446 - processing frame 1
1654287718466 - processing frame 1
1654287718466 - writing frame: frame_offset 576244, frame_ptr 40366254, frame_length 3162
1654287718486 - processing frame 2
1654287718506 - processing frame 2
1654287718526 - processing frame 2
1654287718526 - writing frame: frame_offset 579472, frame_ptr 40366ef0, frame_length 2984
1654287718546 - processing frame 3

Where it rewinds and processes multiple times, but things still seems to work.

Could you explain how you figured out the values? Really curious after spending several hours.

roger- avatar Jun 03 '22 20:06 roger-

Could you explain how you figured out the values? Really curious after spending several hours.

TABLE_HIGH_OFFSET is the offset where the table starts. The record starts with "01 01 00 00" and it's the same as the other models. TABLE_LOW_OFFSET is when table high finishes. You can see a "16 bytes jump" on the pattern. TABLE_RECORD_SIZE is simple: check the pattern in the table. TABLE_RECORD_NUM is TABLE_LOW_OFFSET - TABLE_HIGH_OFFSET / 32 (approximately) BUF_SIZE is the size of the file STREAM_HIGH_OFFSET is where the stream starts. This is not simple because it seems starting at offset 0x177A0 but if you try to calculate, it doesn't work. Example:

  • Use your file view3
  • Find the record with the largest counter: record at 0x3430, counter= 0x5765
  • Read the offset of the stream: 0x12d940
  • Calculate the total offset: 0x177A0 + 0x12d940 = 0x1450e0
  • Go to 0x1450e0 and check if a frame starts: no, there is no frame starting there (00 00 00 01)
  • But if you check at 0x1450a0 you can find the frame
  • So, probably STREAM_HIGH_OFFSET is 0x17760

STREAM_LOW_OFFSET (same as STREAM_HIGH_OFFSET) FRAME_COUNTER_OFFSET is the offset of the counter in the record (2 bytes) = 18 FRAME_OFFSET_OFFSET is the offset of the offset where the stream starts (4 bytes) = 4 FRAME_LENGTH_OFFSET is the offset of the length in the record (4 bytes) = 8

roleoroleo avatar Jun 03 '22 21:06 roleoroleo

Makes sense, thanks.

The record starts with "[01 01 00 00]”…

That part I didn’t realize. I was looking for “[00 00 01]”.

I assume there’s audio data in there too. Any idea how to get that? Seems like the RTSP server doesn’t support audio though.

roger- avatar Jun 03 '22 21:06 roger-

The record in the table starts with 01 01 00 00. The video frame starts with a NALU 00 00 00 01.

I never checked if there is audio in the file, probably yes. I could check in you files.

RTSP server supports audio.

roleoroleo avatar Jun 04 '22 07:06 roleoroleo

Audio table seems starting at ~~0x103d0~~ 0xfa50 Frames at 0x2b7760 You can find AAC headers: FF F1 6C ...

But the grabber, at the moment, doesn't support audio.

roleoroleo avatar Jun 04 '22 12:06 roleoroleo

I checked the v5 rtsp server and I don't see any audio support?

Also I noticed that when using the new parameters you found with the high stream, after a few minutes the video stops and I only see messages like this:

1654303962772 - processing frame 295
1654303962803 - processing frame 295
1654303962833 - processing frame 295
1654303962863 - processing frame 295
1654303962892 - processing frame 295
1654303962922 - processing frame 295
1654303962952 - processing frame 295
1654303962983 - processing frame 295
1654303963012 - processing frame 295

roger- avatar Jun 04 '22 12:06 roger-

I checked the v5 rtsp server and I don't see any audio support?

I removed audio support from v5 version. But it's working on MStar and Allwinner platforms.

Also I noticed that when using the new parameters you found with the high stream, after a few minutes the video stops and I only see messages like this:

Maybe, little tuning is needed. But I don't own a cam of this type (no hisilicon based cams).

roleoroleo avatar Jun 04 '22 13:06 roleoroleo

Do you think one of the offsets needs adjusting?

I’m wondering if the grabber needs to restart searching for the latest record when it gets repeatedly stuck on a frame.

roger- avatar Jun 04 '22 13:06 roger-

I don't know exactly. We should investigate what happens when the stream space circulates. When the space in the stream finishes, what happens?

Your log means that the grabber is unable to find the next frame (number 296) and continues to loop around 295. Please, capture a long long log and share it with me.

roleoroleo avatar Jun 04 '22 13:06 roleoroleo

Seems like it circulates correctly multiple times before it eventually gets stuck. Recording a logfile now, will send when it fails.

Here's an example of what I mean about changing the grabber. Have to set up the SDK before I can test.

roger- avatar Jun 04 '22 18:06 roger-

Here's a log file.

roger- avatar Jun 04 '22 18:06 roger-

Seems like it circulates correctly multiple times before it eventually gets stuck. Recording a logfile now, will send when it fails.

Here's an example of what I mean about changing the grabber. Have to set up the SDK before I can test.

You are right. What happens (in my code) when the frame counter reaches the maximum valute? I wonder how it has worked so far.

The log is not enough. I need to build a new version with a more detailed log.

roleoroleo avatar Jun 05 '22 18:06 roleoroleo

BTW I've identified the IPC messages for motion on the 21CN and added MQTT support. Wonder if v5 can eventually add support for it?

roger- avatar Jun 05 '22 21:06 roger-

I'm a contributor of this repo and I can push commits. But I don't own a cam of this type, so I can't test it. You should ask to @alienatedsec

roleoroleo avatar Jun 06 '22 11:06 roleoroleo

I'm a contributor of this repo and I can push commits.

But I don't own a cam of this type, so I can't test it.

You should ask to @alienatedsec

@roleoroleo Please commit The change. I also don't have a CN model but @roger- will be more than happy to test, right?

alienatedsec avatar Jun 06 '22 11:06 alienatedsec

Please, try this binary and run it until it loops in "processing frame xxx". And post the log. h264grabber.gz

roleoroleo avatar Jun 07 '22 12:06 roleoroleo

The first time I ran it (without saving the logs), it ran for a while and started looping. Now its been running for 30 mins with no issues, but the log looks strange:

1654606611291 - processing frame 415, frame_counter 4805
1654606611291 - current frame is 4805, next frame is 56056
1654606611292 - writing frame: frame_counter 4805, frame_offset 651208, frame_ptr 402e0728, frame_length 3313
1654606611321 - processing frame 416, frame_counter 4805
1654606611321 - current frame is 4805, next frame is 56057
1654606611322 - writing frame: frame_counter 4805, frame_offset 654588, frame_ptr 402e145c, frame_length 3378
1654606611353 - processing frame 417, frame_counter 4805
1654606611354 - current frame is 4805, next frame is 0
1654606611381 - processing frame 417, frame_counter 4805
1654606611386 - current frame is 4805, next frame is 56058
1654606611387 - writing frame: frame_counter 4805, frame_offset 658032, frame_ptr 402e21d0, frame_length 3211
1654606611421 - processing frame 418, frame_counter 4805
1654606611421 - current frame is 4805, next frame is 56059
1654606611422 - writing frame: frame_counter 4805, frame_offset 661308, frame_ptr 402e2e9c, frame_length 3280
1654606611452 - processing frame 419, frame_counter 4805
1654606611452 - current frame is 4805, next frame is 0
1654606611481 - processing frame 419, frame_counter 4805
1654606611481 - current frame is 4805, next frame is 56060
1654606611482 - writing frame: frame_counter 4805, frame_offset 664652, frame_ptr 402e3bac, frame_length 3213
1654606611512 - processing frame 420, frame_counter 4805
1654606611512 - current frame is 4805, next frame is 0
1654606611541 - processing frame 420, frame_counter 4805
1654606611541 - current frame is 4805, next frame is 56061
1654606611542 - writing frame: frame_counter 4805, frame_offset 667932, frame_ptr 402e487c, frame_length 3278
1654606611581 - processing frame 421, frame_counter 4805
1654606611581 - current frame is 4805, next frame is 56062
1654606611582 - writing frame: frame_counter 4805, frame_offset 671276, frame_ptr 402e558c, frame_length 3397
1654606611611 - processing frame 422, frame_counter 4805
1654606611612 - current frame is 4805, next frame is 0
1654606611641 - processing frame 422, frame_counter 4805
1654606611641 - current frame is 4805, next frame is 56063
1654606611642 - writing frame: frame_counter 4805, frame_offset 674740, frame_ptr 402e6314, frame_length 3228
1654606611671 - processing frame 423, frame_counter 4805
1654606611672 - current frame is 4805, next frame is 0

Notice, for example, how next frame is 0 shows up frequently.

I'll post a full log once it starts looping again.

roger- avatar Jun 07 '22 13:06 roger-

Interesting. I don't know why the current frame counter is stuck at 4805 and next frame counter increases.

The "next frame is 0" shouldn't be a problem: probably it is trying to read the record before it's ready.

roleoroleo avatar Jun 07 '22 14:06 roleoroleo

Another test please: h264grabber.gz

roleoroleo avatar Jun 07 '22 14:06 roleoroleo

Got stuck pretty quickly this time.

Ran with:

./h264grabber -m yi_home -r HIGH -d -f  --buf_size 3110752 --table_record_num 500 --stream_offset 96096 2>&1 | tee /tmp/hd1/out.log

roger- avatar Jun 07 '22 14:06 roger-

All right, one more time around the block: h264grabber.gz

This beta could be ok. It also contains your proposals.

roleoroleo avatar Jun 07 '22 15:06 roleoroleo

Thanks, but things got worse with this one and no video at all: out.log

Lots of "frame counter invalid, sync lost" messages and it rarely successfully writes. Didn't loop though I think (stopped it early).

roger- avatar Jun 07 '22 15:06 roger-

h264grabber.gz

roleoroleo avatar Jun 07 '22 15:06 roleoroleo

This one works better: out.log

The video does pause periodically though (maybe around every 5-10 seconds for 1-2 seconds, e.g. at t=1654616720751) and I still see lots of "frame counter invalid" messages

roger- avatar Jun 07 '22 15:06 roger-

The log is "perfect". It doesn't show lost frames and all errors are properly handled.

"frame counter invalid" message is not a problem, it happens (normally) when next frame counter is 0 but the process tries again after 10 millis. The real error is when "frame counter invalid" is followed by a "sync lost".

You should test what happens when the frame counter reaches 65535 and restarts from 0.

So, why the video does pause? Try to save the file and play it with vlc, maybe the problem is in the rtsp part.

roleoroleo avatar Jun 07 '22 16:06 roleoroleo

Left it running for a couple hours with no crashing or looping, but not sure if the frame counter rolled over. One thing I noticed was that the camera was getting really slow and laggy (telnet and video). When I killed the RTSP server everything went back to normal, so I think you're right about that being the problem.

To confirm I saved the raw video using:

./h264grabber -m yi_home -r HIGH -d  --buf_size 3110752 --table_record_num 500 --stream_offset 96096 > /tmp/hd1/test.h264

And was able to play it back using:

vlc test.h264 --demux h264

Video seemed more or less perfect (might have been some blocking artifacts), so I'm fairly confident the RTSP server is causing the system to slow down and creating the pauses in the video.

Do you know of any static ffmpeg binaries that work on these cameras? I perhaps test that as a way to stream instead.

roger- avatar Jun 07 '22 18:06 roger-

I will check the rtsp server.

Do you know of any static ffmpeg binaries that work on these cameras? I perhaps test that as a way to stream instead.

https://github.com/roleoroleo/yi-hack-utils

roleoroleo avatar Jun 08 '22 08:06 roleoroleo