Chrome memo

To prevent inactive tab from using cpu resources, in address bar, visit

1
chrome://discards

toggle restless pages 'Urgent Discard' to grey under 'Actions' column.

chrome://flags#

enable-parallel-downloading
enable-force-dark

refer to:
https://www.askvg.com/tip-enable-tab-freeze-or-tab-suspend-feature-in-google-chrome/
https://blog.csdn.net/ythuiyi/article/details/113506238

Rendering mp4 video not silky, why?

The original HD mp4 file 'movie.mp4' plays very smoothly. I picked out the h264 stream saved as 'movie.264' from it, then using mp4v2 converted 'movie.264' to a new mp4 file 'output.mp4'. However, experience of watching 'output.mp4' was very bad. Why?

I debugged the 'ClipTrack' function in 'mp4v2/test/OLD/mp4clip.cpp', found a key argument 'renderingOffset' of function 'MP4WriteSample'. All examples searched from the web about writing h264 to mp4 through mp4v2 set 'renderingOffset' to 0, while in 'ClipTrack', 'renderingOffset' of the function 'MP4WriteSample' is directly set to the value from 'renderingOffset' of the function 'MP4ReadSample'.

Here we make a concept clear, the 'sample' entity in mp4 file format specification is equal to a frame which can completely rendering as a picture. A sample consists of several nalus, a nalu whose start code is 0x00, 0x00, 0x00, 0x01 indicates a new sample, while a nalu which starts with 0x00, 0x00, 0x01 is among a sample, and a sample needs not to be a IDR key frame.

Through carrying 'renderingOffset' value at beginning of each sample in 'movie.264', I did generate an 'output.mp4' which displays as smoothly as the original one.

Did 'renderingOffset' mean time stamp of a sample? No, at least not exactly. By watching log, I found its value was not increasing as time went by.

I continued debugging mp4v2, then saw a key word 'ctts' atom, and searched a link from the web,

https://blog.csdn.net/cheyo809775692/article/details/100924523

I now understand, the decoding order of h264 samples is slightly different from the rendering order of them.

For example, in stts atom,

1
2
3
4
5
'decoding order'	'sample count'		'sample duration'
1,2,3,4			4			20
5			1			40
6,7,8			3			20
9			1			60

in ctts atom,

1
2
3
4
5
6
7
8
'decoding order'	'sample count'		'sample offset'
1,2,3			3			20
4			1			40
5			1			0
6			1			40
7			1			0
8			1			40
9			1			0

final rendering timing is

1
2
3
'decoding order'	1	2	3	4	5	6	7	8	9
'duration'		20	20	20	20	40	20	20	20	60
'rending order'			1	2	3	5	5,4	7	6	9	9,8	9

Terms,

1
2
3
4
5
6
7
8
9
10
11
12
mvhd: movie header
tkhd: track header
mdhd: media header
stsd: sample descriptions
stts: time to sample
ctts: composition offset
stss: sync sample offset
stsc: sample to chunk
stsz: sample size
stco/stco64: chunk offset
dts: decoding timestamp
pts: presentation timestamp

expect scp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
auto_scp()
{
	local filepath=$1
	expect -c "
		set timeout 10
 
		spawn scp scp://someone@192.168.12.3:1234//home/someone/$filepath .
 
		expect \"password:\" 
		send \"toodangerous\r\"
 
		interact
	"
}

refer to:
https://blog.csdn.net/f_zyj/article/details/93475830
https://zhuanlan.zhihu.com/p/25164676

Select Windows SDK version when building using cmake

Read cmake online doc carefully, https://cmake.org/cmake/help/latest/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.html

So when we build project which has CMakeLists.txt, we can select Windows SDK version in this way:

  1. In explorer, navigate to like C:\Program Files (x86)\Windows Kits\10\Include.
  2. For cmake always finds the newest version to build our project, we can just rename all sdk versions which is newer than we want. e.g. if we want 10.0.19041.0 to build our project, but 10.0.22581.0 is newer, we rename 10.0.22581.0 to 10.0.0.22581.0, the rule is among tokens split by period signs, the third token number is the key word that cmake sorts them to get the largest as newest.
  3. Start cmake to configure the project, it will find the right sdk version.
  4. After cmake is done in configuration, rename 10.0.0.22581.0 back to 10.0.22581.0.

LD_LIBRARY_PATH in makefile

At a glance,

1
2
3
dbg:
	set LD_LIBRARY_PATH=/path/to/so
	echo ${LD_LIBRARY_PATH}

Why does the 'echo' command output nothing?

For the dollar sign is not only a key letter in bash, it's also in makefile. And each command line in Makefile shares no environmental variables. So right way is

1
2
3
dbg:
	set LD_LIBRARY_PATH=/path/to/so ; \
	echo $${LD_LIBRARY_PATH}

However, if tst01 needs to load libtst02.so from /path/to/so/,

1
2
dbg:
	set LD_LIBRARY_PATH=/path/to/so ; ./tst01

why does tst01 still report it can't find libtst02.so?

For the 'set' command only lets LD_LIBRARY_PATH variable visible in the bash process where the 'set' is invoked, no spreading in child processes. So final correct script is

1
2
dbg:
	export LD_LIBRARY_PATH=/path/to/so ; ./tst01

logc needs rewritting

For the thing is changing, loge will not call logi by itself, we need invoke !logexts.logi explicitly in advance.

The up to date procedure is

  1. LogManifest.lgm is in wrong place, so

    1
    2
    
    cd C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext
    copy LogManifest.lgm ..
  2. Start WinDbg, click main menu, File, Open Executable...
  3. In command bar of WinDbg, input

    1
    2
    3
    4
    
    !logexts.logi
    g
    !logir
    g

We will find a folder named ApiLogs lying on the Windows desktop. After the debuggee process exits, by using logviewer.exe we can open files in it, with .lgx suffix.

Automatically distill headers from other project

catch_inc.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash
 
dir_cur=`pwd`
dir_inc=original_inc
dir_src=/path/to/other/project
 
withly()
{
	[ -e $2 ] && $*
}
 
withoutly()
{
	[ -e $2 ] || $*
}
 
withly rm inc.makefile1
withly rm Makefile
 
if [ x$1 == xclean ] ; then
	withly rm inc.makefile
	withly rm ${dir_inc} -Rf
	exit 0
fi
 
withoutly mkdir ${dir_inc}
withoutly touch inc.makefile
 
while [ 1 ] ; do
	cat inc.makefile | sort | uniq > inc.makefile1
	cp inc.makefile1 inc.makefile
	cat inc.makefile | sed ':t;N;s/\n//;b t' | sed 's/\//\\\//g' | sed 's/\ /\\\ /g' > inc.makefile1
	sed "s/@original_includes@/`cat inc.makefile1`/g" Makefile.pat > Makefile
	lost_header=`make 2>&1 | grep "#include" | awk '{if ($2 == "|" && $3 == "#include") print $4}' | awk -F\" '{print $2}'`
	if [ x${lost_header} == x ] ; then
		break
	fi
	found_header=`cd ${dir_src}; find . -name ${lost_header} | head -n 1`
	echo ${found_header}
	found_header=${found_header##./}
	( cd ${dir_src}; cp --path ${found_header} ${dir_cur}/${dir_inc}/ )
	found_header=`dirname ${found_header}`
	echo "-I${dir_inc}/${found_header} " | cat >> inc.makefile
done

For an example, pattern file Makefile.pat is as

1
2
3
4
...
CFLAGS=-g -Iinclude @original_includes@
LDFLAGS=-pthread -lm
...

from which the catch_inc.sh script can generate Makefile like

1
2
3
4
...
CFLAGS=-g -Iinclude -Ioriginal_inc/subdir/in/other/project/inc1 -Ioriginal_inc/subdir/in/other/project/common/inc2
LDFLAGS=-pthread -lm
...

refer to:
https://www.cnblogs.com/liqiu/p/4506508.html

Hardware memo

1
2
3
4
5
6
7
8
PWM	Pulse Width Modulation
SPI	Serial Peripheral Interface			MISO MOSI SCLK CS
UART	Universal Asynchronous Receiver/Transmitter	Rx Tx GND
USB	Universal Serial Bus				VBUS D- D+ GND
AMBA	Advanced Microcontroller Bus Architecture	AHB ASB APB
MIPI	Mobile Industry Processor Interface
LVDS	Low Voltage Differential Signaling
CFA	Color Filter Arrays

HiSi

1
2
3
4
5
6
7
8
9
NNIE	DPU
IVE	ISP
VI	Video Input
VO	Video Output
VPSS	Video Processing Sub System
AVS	Video Splicing
MMZ	Media Memory Zone
VB	Video Buffer
NR	Noise Reduction

refer to:
https://www.cnblogs.com/qinghaowusu/p/13610568.html

h264 memo

AVC		Advanced Video Coding, alias h264

SODB	String Of Data Bits
RBSP	Raw Byte Sequence Payload
		RBSP = SODB + (RBSP Trailing Bits for alignment)

EBSP	Encapsulated Byte Sequence Payload
		EBSP = RBSP inserted 0x03 to avoid being treated as startcode of a NALU
		Raw data
			... 0xXX, 0x00, 0x00, 0xXX, ...
		Encoded data
			... 0xXX, 0x00, 0x00, 0x03, 0xXX, ...
NALUHeader
		forbidden_zero_bit, 1bit
		nal_ref_idc, 2bits
		nal_unit_type, 5bits, equals NALUHeader & 0x1F

NALU	Network Abstraction Layer Unit
		NALU = NALUHeader + EBSP
		startcode
			0x00, 0x00, 0x01		Following NALU is a slice in one picture frame
			0x00, 0x00, 0x00, 0x01	Following NALU is a picture frame, SPS, PPS, etc
AU		Access Units
			A complete picture frame containing several NALUs

SPS		Sequence Parameter Set				nal_unit_type == 7
			From an SPS, we can get width and height of the picture

PPS		Picture Parameter Set					nal_unit_type == 8
IDR		Instantaneous Decoding Refresh			nal_unit_type == 5
SEI		Supplemental Enhancement Information	nal_unit_type == 6
			1 byte payloadType + 1 byte payloadSize
			payloadType
				0x00: buffering_period
				0x01: pic_timing
				0x02: pan_scan_rect
				0x03: filler_payload
				0x04: user_data_registered_itu_t_t35
				0x05: user_data_unregistered
					16 bytes: uuid_iso_iec_11578
					payloadSize - 16: user_data_payload_byte
				0x06: recovery_point
			rbsp trailing bits
AnnexB
		use startcode
AVCC
		use NALU length, reuse EBSP
RTP
		in AVCC, not AnnexB?

refer to:
https://www.cnblogs.com/ssyfj/p/14624498.html
https://blog.csdn.net/y601500359/article/details/80943990

Priority of operator

Upper operators are more preemptive than lower ones.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
left to right	[] () . -> rear++ rear--
right to left	front++ front-- sizeof & * +(positive) -(negitive) ~ !
right to left	(mandatory transform)
left to right	.* ->*
left to right	* / %
left to right	+ -
left to right	<< >>
left to right	< > <= >=
left to right	== !=
left to right	&
left to right	^
left to right	|
left to right	&&
left to right	||
right to left	?:
right to left	= *= /= %= += -= <<= >>= &= ^= |=
left to right	,

refer to:
https://blog.csdn.net/l2014010671/article/details/104636916