这篇文章缩减了不少内容。
Emscripten toolchain是WebAssembly的第一个工具,它模拟了一个特别的OS 系统在web 接口,也可以允许开发者使用libc。Emscripten Compiler Frontend(EMCC)可以直接看成类似gcc的工具。emcc可以使用Clang或者LLVM编译成wasm或者asm.js文件。
这个不用说了,就是一个标准的编译器集合。
JavaScript文件镶嵌在HTML中,当然也需要借助浏览器进行查看。那么,如果不用浏览器怎么运行呢?这个时候就需要借助JS的runtime (Node.js)去跑了。
该Runtime内部包含一个WebAssembly VMcore(iwasm).
Wasmer是一个非浏览器的、支持WASI和Emscription
https://liux120.github.io/ECE202_WASM/
这个命令真的值得花一点时间去记录。
最简单,如果处理.gz的文件,需要使用”-z“参数,符合认知。如果是bz2,需要使用”-j”选项。
“-x”
“-v”: verbose
“-f”: file name
将qemu目录压缩成gz包。
tar -czvf qemu-bak.tar.gz qemu # 源目录在后面
将上述压缩包解压
tar -zxvf qemu.tar.gz qemu # 目标文件在后面
首先创建文件夹: mkdir tmp-dir,然后使用 “-C” 参数解压到制定目录。
tar -zxvf qemu.tar.gz -C tmp-dir
tar xf gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
tar --owner root --group root -cjf kernel_supplements.tbz2 lib/modules
这条命令是压缩成 tbz2 文件,且带着相应的权限。具体的作用就是把 lib/modules目录下 的文件压缩成kernel_supplements.tbz2 文件。
参考这个链接: https://www.cnblogs.com/hh2737/p/7710830.html
如果打包一个文件夹比如一个dts文件,那么正常情况下我是压缩的这个包,但是,如果在项目中需要 我们把dts下的东西直接解压到 dtb 目录下,这样是不行的。因为解压的时候,正常是在 dtb/dts的。 那么,这就需要我们在压缩的时候做一些改动。
有两种方式可以解决这个问题:
tar zcf dts.tar.gz *
这种方式会不会把这在生成的tar包也压缩进去,这值得我们怀疑,但是据我观察,好像不会的。
tar -zcf dts.tar.gz -C dts/ .
尤其别忘了后面的那一个”.”
初始化一个rust项目。
vimer@host:~/test/rust_2$ ls
Cargo.toml src/
rust的源代码可以放在这个目录下面。
vimer@host:~/test/rust_2$ cargo run
Compiling rust_2 v0.1.0 (/home/vimer/test/rust_2)
Finished dev [unoptimized + debuginfo] target(s) in 0.13s
Running `target/debug/rust_2`
Hello, world!
cargo run可以直接执行rust程序(当然是经过编译过后的),这样就省去了编译、执行的过程。
这个方式和python的import的道理是相同的。例子:
vimer@host:~/test/rust_2/src$ cat print.rs
pub fn run(){
println!("hell from run");
}// 这里必须有 pub 修饰词
main.rs:
vimer@host:~/test/rust_2/src$ cat main.rs
mod print; // 引入文件名,去掉后缀名
fn main() {
println!("Hello, world!");
print::run(); // mod name and fun
}
执行后的结果为:
vimer@host:~/test/rust_2/src$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `/home/vimer/test/rust_2/target/debug/rust_2`
Hello, world!
hell from run
再次强调一遍, 如果引入外部的函数,需要在声明函数的时候键入关键词pub
.
fn greeting(greet: &str, name: &str){
println!("{}, {},nice to meet you", greet, name);
}
fn main() {
greeting("hello,", "vimer")
} // 参数,使用 &str表示表类型
返回值:
// 返回值, 使用->进行暗示
fn add(n1: i32, n2: i32) -> i32{
n1 + n2
} // 注意 n1 + n2 后面没有 ;
fn main() {
let get_sum = add(5,3);
println!("Sum: {}", get_sum);
}
还有一种近似的函数:
let add_nums = |n1:i32, n2:i32| n1 + n2 + n3;
println!("C sum: {}", add_nums(3,3));
// print 16
这个应该和C的指针差不多。
let arr1 = [1,2,3];
let arr2 = arr1;
println!("Values: {:?}", (arr1, arr2));
// print
//
//Vector
let vec1 = vec![1,2,3];
let vec2 = &vec1;
println!("Values: {:?}", (&vec1, vec2));
// Values: ([1, 2, 3], [1, 2, 3])
// Values: ([1, 2, 3], [1, 2, 3])
struct Color {
red: u8,
green: u8,
blue: u8,
}
fn main() {
let mut c = Color {
red: 255,
green: 0,
blue: 0,
};
println!("Color : {} {} {}", c.red, c.green, c.blue);
}
还有下面的这种方式也行:
struct Test (u8, u8, u8);
let mut c = Test(255, 0, 0);
一个更复杂的例子:
struct Person{
first_name: String,
last_name: String,
}
impl Person{
// Construct
fn new(first: &str, last: &str) -> Person{
Person {
first_name: first.to_string(), // Convert original struct member
last_name: last.to_string(),
}
}
// Get full name
// format?
fn full_name(&self) -> String {
format!("{} {}", self.first_name, self.last_name)
}
// Set last name
// ??
fn set_last(&mut self, last:&str) {
self.last_name = last.to_string();
}
// Name to tupel
fn to_tuple(self) ->(String, String) {
(self.first_name, self.last_name)
}
}
fn main(){
let mut p = Person::new("Mary", "Doe");
println!("Full name is {}", p.full_name());
p.set_last("vimer");
println!("Full name is {}", p.full_name());
println!("Tuple name is {:?}", p.to_tuple());
}
/* output:
Full name is Mary Doe
Full name is Mary vimer
Tuple name is ("Mary", "vimer")
*/
函数有返回值的,函数体没有最后的”;”.
enum Movement {
Up,
Down,
Left,
Right
}
fn move_avator(m: Movement) {
match m {
Movement::Up => println!("Up"),
Movement::Down => println!("Down"),
Movement::Left => println!("Left"),
Movement::Right => println!("Right")
}
}
fn main(){
let avatar1 = Movement::Up;
let avatar2 = Movement::Down;
let avatar3 = Movement::Left;
let avatar4 = Movement::Right;
move_avator(avatar1);
move_avator(avatar2);
move_avator(avatar3);
move_avator(avatar4);
}
/* output:
Up
Down
Left
Right
*/
还是要注意 match 中的符号问题。
use std::env;
fn main(){
let args: Vec<String> = env::args().collect();
println!("Args: {:?}", args);
}
// Args: ["/home/vimer/test/rust_2/target/debug/rust_2"]
vimer@host:~/test/rust_2/src$ cargo run hello
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `/home/vimer/test/rust_2/target/debug/rust_2 hello`
Args: ["/home/vimer/test/rust_2/target/debug/rust_2", "hello"]
let cmd = args[1].clone();
首先要根据官网的指令把rust安装到pc上,其包管理器是Cargo.
fn main() {
println!("hello, world");
}
保存为文件为 hello.rs. 然后使用命令rustc hello.rs
去编译生成hello的二进制文件。
rust的注释有三种,其中”/**/”和”//”与c/c++的注释方式一致,第三种方式是
/// Doc which are parsed into html, begin
//! end
上面的println!就是将文本打印到console上并换行。
println!("{ } days", 31);
println!("{0}, this is {1}, {1} this is {0}", "yubo", "hechun");
”{}”会自动替换任何参数。指示词可以使用0和1自动填入参数,这样的参数在这里叫做位置参数Positional arguments。
还可以有 Named arguments. 比如下面这种:
// name arg:
println!("{sub} {verb} {obj}",
obj="vimer",
verb="hello",
sub = "test");
// {:b} print it with binary format
println!("{} of {:b} know binary, the other half does not", 1, 2);
// Right-align text with a special width
println!("{number:>width$}", number=1, width=6);
output:
test hello vimer
1 of 10 know binary, the other half does not
1
// Right-align text with a special width
println!("{number:>width$}", number=1, width=6);
println!("{number:>0width$}", number=1, width=6);
/*
1 of 10 know binary, the other half does not
1
000001
*/
以上的代码中,包含了格式(二进制b,对其, 填充)等格式说明。
如果位置参数确实怎么办? rust会直接给你报错。
println!("my name is {0}, and your name is {1}, {1} this is {0}", "vimer");
error:
error: invalid reference to positional argument 1 (there is 1 argument)
--> hello.rs:2:47
|
2 | println!("my name is {0}, and your name is {1}, {1} this is {0}", "vimer");
| ^^^ ^^^
|
= note: positional arguments are zero-based
error: aborting due to previous error
”” to debug rust program
Rust的类型比较特殊,是需要值得注意点。
fn main() {
// Variables can be type annotated.
let logical: bool = true;
let a_float: f64 = 1.0; // Regular annotation
let an_integer = 5i32; // Suffix annotation
// Or a default will be used.
let default_float = 3.0; // `f64`
let default_integer = 7; // `i32`
// A type can also be inferred from context
let mut inferred_type = 12; // Type i64 is inferred from another line
inferred_type = 4294967296i64;
// A mutable variable's value can be changed.
let mut mutable = 12; // Mutable `i32`
mutable = 21;
// Error! The type of a variable can't be changed.
mutable = true;
// Variables can be overwritten with shadowing.
let mutable = true;
}
下面的代码把rust基本的数据总结下来了:
fn main() {
println!("1+2={}", 1u32+2); // 3
println!("1-2={}", 1i32-2); // -1
println!("true and false is {}", true && false);// true and false is false
println!("true or false is {}", true || false); // true or false is true
println!("Not true is {}", !true); // Not true is false
// bitwise
println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101u32); //0011 AND 0101 is 0001
println!("0011 or 0101 is {:04b}", 0b0011u32 | 0b0101u32);//0011 or 0101 is 0111
println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101u32); //0011 XOR 0101 is 0110
println!("1 << 5 is {}", 1u32 << 5); // 1 << 5 is 32
println!("0x80 >> 2 is {:x}", 0x80u32 >> 2); //
println!("One million is written as {}", 1_000_000u32);// One million is written as 1000000
}
该修饰符可以改变变量的属性,主要是否可以改变其值的属性。
// first
let long_tuple = (1u8, 2u16, 3u32, 4u64,
-1i8, -2i16, -3i32, -4i64,
0.1f32, 0.2f64,
'a', true);
// print content of tuple of indexing
println!("first value {}", long_tuple.0);
println!("second value {}", long_tuple.1);
let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);
// print tuples, 元组中有元组可以打印,
println!("tuple of tuples: {:?}", tuple_of_tuples);
let too_long_tuple = (1,2,3,4,5,6,7,8,9,10);
println!("long tuple :{:?}", too_long_tuple); // 之前版本是不可以的,但是目前是可以的了
// make pair for tuple
let pair = (1, true);
println!("pair is {:?}",pair);
// 如果需要只打印一个元素的tuple,则需要","进行分割
println!("the one element tupleis {:?}", (8i8,)); //p: the one element tupleis (8,)
// 如果只有一个元素,就是单单打印一个元素
println!("the one element {:?}", (8i8)); //p: the one element 8
// second
let age = 28; // can not reassign value
let mut age = 28;
age = 36; // is ok
const ID: i32 = 001; // ok
// Assign multiple vars
let (my_name , my_age ) = ("Brad", 37);
println!("{} is {}, my_name, my_age");
println!("Max i32 is {} and i64 is {}", std::i32::MAX, std::i64::MAX);
rust是一个基于 block 的语言。
rust提供两种string的声明。一种是char*的形式,另一种是直接使用内置方法, 基于heap的内存模型。
// 1
let hello = "Hello"; // It is fixed-len string in memory
// 2
let hello = String::from("hello");
println!("Length: {}",hello.len());
下面是个有趣的例子:
fn main() {
let hello = String::from("hello ");
hello.push("world");
println!("{}", hello);
} // error! 1. let is default behave for immutable
// 2. push() is only for a word
//3. push_str() is supported for string
// right code :
fn main() {
let mut hello = String::from("hello ");
hello.push_str("world");
hello.push('!');
println!("{}", hello);
}
String的属性有
for word in hello.split_whitespace(){
println!("{}", word);
}
// hello
// world!
let mut s = String::with_capacity(10);
s.push('a');
s.push('b');
assert_eq!(3, s.len); // debug track
Tuple group together value of different types, max is 12
let person: (&str, &str, i8) = ("yubo", "vimer", 28);
println!("{} is form {} and is {}", person.0, person.1, person.2);
It is the same elements in a array.
let num: [i32;5] = [1,2,3,4,5]; // [ypye; num]
println!("{:?}", num);
// 1. 少一个元素都不行的
// 2. get a single val
println!("{}", num[3]);
// 3. reassign value
// 4. Arrays are stack
println!("Array occupies {} bytes", std::mem::size_of_val(&num));
/* Array occupies 20 bytes
*/
std还可以使用 use std;
在rs源文件开始的地方。
Slices这里可以看成切片,同python的用法差不多。可以由 array 转化而来。
let slice: &[i32] = #
println!("Slices is {:?}", slice);
// Slices is [1, 2, 3, 4, 5]
如果在使用切片时指定下标,则使用符号..
let slice: &[i32] = &num[0..2];
println!("Slices is {:?}", slice);
// Slices is [1, 2]
Vector is resize array, 目前看与array没有太大的区别。
fn main() {
let mut num: Vec<i32> = vec![1,2,3,4,5];
println!("{:?}", num);
println!("{}", num[3]);
// reassign value
num[3] = 20;
println!("Array occupies {} bytes", std::mem::size_of_val(&num));
let slice: &[i32] = &num[0..2];
println!("Slices is {:?}", slice);
}
则输出为:
[1, 2, 3, 4, 5]
4
Array occupies 24 bytes
Slices is [1, 2]
当然可以使用 push(), pop(),loop through vector values
for x in num.iter() {
println!("number: {}", x);
} // this is immut_value
for x in num.iter_mut() {
*x +x = 2;
}
let age = 22;
let check_id: bool = false;
if age >= 21 && check_id{
println!("haha");
} else {
println!("no you are not");
}
// short of if
let is_of_age = if age >= 21 { true } else { false };
let mut count = 0;
// infinite
loop {
count += 1;
println!("Number: {}", count);
if count == 20 {
break;
}
}
/*
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Number: 6
Number: 7
Number: 8
Number: 9
Number: 10
Number: 11
Number: 12
Number: 13
Number: 14
Number: 15
Number: 16
Number: 17
Number: 18
Number: 19
Number: 20
*/
while count <= 50 {
if count % 15 == 0 {
println!("fizzbuzz");
} else if count % 3 == 0 {
println!("fizee");
} else if count % 5 == 0{
println!("buzz");
} else {
println!("no {}", count);
}
count += 1;
}
The same result as above code:
for count in 0..50 {
if count % 15 == 0 {
println!("fizzbuzz");
} else if count % 3 == 0 {
println!("fizee");
} else if count % 5 == 0{
println!("buzz");
} else {
println!("no {}", count);
}
}
目前的c++还是熟悉数据结构的阶段,所以总结记录下。
作为工具就是,该容器的效率为O(1).常用方法有:
#include <unordered_map>
#include <iostream>
#include <vector>
using namespace std;
int main() {
unordered_map<string, vector<int>> keys;
keys["a"] = vector<int>(); // Initialize key with all null vector
keys["a"].push_back(1);
keys["a"].push_back(2);
for (const int &x : keys["a"]){
cout << x << endl;
}
/* Above code is store a int array with string */
/* insert value by [] oper */
unordered_map<string, double> umap;
umap["PI"] = 3.14;
umap["root2"] = 1.414;
umap["user1"] = 2.302;
/* insert value by insert function */
umap.insert(make_pair("e", 2.78));
string key = "PI";
if (umap.find(key) == umap.end())
cout << key << "not found\n\n";
else
cout << "found " << key << "\n";
key = "lambda";
if (umap.find(key) == umap.end())
cout << key << "not found" << "\n";
else
cout << "found " << "\n";
/* iterator elements with iter */
unordered_map<string, double>::iterator iter;
for (iter = umap.begin(); iter !=umap.end(); iter++){
cout << iter->first << " " << iter->second << endl;
}
}
1.发现摄像头设备
# On linux:
vimer@host:~/pic$ v4l2-ctl --list-devices
HD Camera: HD Camera (usb-0000:00:14.0-10):
/dev/video0
/dev/video1
# On windows:
ffmpeg -list_devices true -f dshow -i dummy
[dshow @ 0000014762dda980] DirectShow video devices (some may be both video and audio devices)
[dshow @ 0000014762dda980] "Integrated Camera"
[dshow @ 0000014762dda980] Alternative name "@device_pnp_\\?\usb#vid_5986&pid_02d2&mi_00#7&7f65834&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 0000014762dda980] "HD Camera"
[dshow @ 0000014762dda980] Alternative name "@device_pnp_\\?\usb#vid_0bc8&pid_5880&mi_00#6&19d0255b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 0000014762dda980] DirectShow audio devices
[dshow @ 0000014762dda980] "麦克风阵列 (2- Realtek High Definition Audio)"
[dshow @ 0000014762dda980] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{DB187E2D-D643-4E74-9C68-1FF045E372DC}"
查看摄像头的直播:
~$: cheese (On linux)
ffplay -f dshow -i video="HD Camera" (On Windows)
可以直接使用”HD Camera”.
vimer@host:~/pic$ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1600x1200
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 2048x1536
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 2592x1944
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 3264x2448
Interval: Discrete 0.067s (15.000 fps)
Index : 1
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.050s (20.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 1600x1200
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 2048x1536
Interval: Discrete 0.500s (2.000 fps)
Size: Discrete 2592x1944
Interval: Discrete 0.500s (2.000 fps)
Size: Discrete 3264x2448
Interval: Discrete 0.500s (2.000 fps)
vimer@host:~/pic/test$ v4l2-ctl --device /dev/video1 --stream-mmap --stream-to=frame.raw --stream-count=30
以mmap
方式获取raw frame,stream-to=frame.raw 表明保存的文件为frame.raw 后面的参数指明了帧数(可以指明摄像头的默认帧数)。如果安装 ImageMagick 的话,可以使用下面的命令把raw转换为image。
convert -size 640x480 -depth 16 uyvy:frame10.raw frame10.png
源代码工具可以看这里
在linux和windows使用ffmpeg请参考这个 link
Constant Rate Factor (crf)能决定在转码时的压缩效果,值越高,压缩越高,视频质量就越差。 在 264 和 265 中可以使用 –crf [0-51]. For x264, sane values are between 18 and 28. The default is 23. ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4 For x265, the default CRF is 28:
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
使用ffmpeg录制未压缩的视频(然后进行转码):
ffmpeg -f v4l2 -i /dev/video1 -codec:v copy rawvideo.nut (On linux)
其中,rawvideo.nut大小为260416KB.
ffmpeg -f dshow -i video="HD Camera" -codec:v copy raw_win.nut(On windows)
使用下面的命令将raw文件转换为其他格式。
ffmpeg -i rawvideo.nut -codec:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -movflags +faststart output.mp4
output.mp4大小为 154KB
可以参考这个文件 https://www.ensta-bretagne.fr/zerr/dokuwiki/doku.php?id=gstreamer:main-gstreamer
gst-launch-1.0 -v filesrc location=raw_win20s.nut ! jpegdec ! videoconvert ! autovideosink
(命令释义: 把raw_win20s.nut(jpeg压缩格式)文件以 jpegdec 方式进行解码 ,然后让videoconvert进行自动转码,然后存放于autovideosink) gst以管道的形式传递参数。其中, 例如jpegdec什么的,可以看成元素。至于查看某个元素的具体信息可以使用
gst-inspect-1.0 | grep jpegdec
去查看。 当然, gst-inspect-1.0的信息更全面。
2. gst-launch-1.0 -v v4l2src ! autovideosink (以v4l2为源文件,然后发送至autovideosink)
如果找不到摄像头的合适格式、参数,可以使用使用上面的命令看下log输出,然后填入 caps,测试下面的命令是可以的:
gst-launch-1.0 -v v4l2src device=/dev/video0 ! "video/x-raw, width=(int)3264, height=(int)2448, framerate=(fraction)2/1, format=(string)YUY2, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:6:5:1, interlace-mode=(string)progressive" ! autovideosink
800*600
源文件 编码、大小(du -h) 转码格式-[OS] 大小-时长 命令 评价
raw_linux_dai.nut (rawvideo : YUY2) 344MB libx265 [pc] 368KB-21s ffmpeg -i raw_linux_dai.nut -codec:v libx265 -crf 23 -preset medium -pix_fmt yuv420p -movflags +faststart h265.mp4
raw_linux_dai.nut (rawvideo : YUY2) 344MB libx265 [pc] 224KB-21s ffmpeg -i raw_linux_dai.nut -codec:v libx265 -crf 28 -preset medium -pix_fmt yuv420p -movflags +faststart h265.mp4 最好
raw_linux_dai.nut (rawvideo : YUY2) 344MB libx265 [pc] 188KB-21s ffmpeg -i raw_linux_dai.nut -codec:v libx265 -crf 30 -preset medium -pix_fmt yuv420p -movflags +faststart h265.mp4
raw_linux_dai.nut (rawvideo : YUY2) 344MB libx264 [pc] 912KB ffmpeg -i raw_linux_dai.nut -codec:v libx264 -crf 20 -preset medium -pix_fmt yuv420p -movflags +faststart h264.mp4
raw_linux_dai.nut (rawvideo : YUY2) 344MB libx264 [pc] 568KB ffmpeg -i raw_linux_dai.nut -codec:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -movflags +faststart h264.mp4 最好
raw_linux_dai.nut (rawvideo : YUY2) 344MB libx264 [pc] 284KB ffmpeg -i raw_linux_dai.nut -codec:v libx264 -crf 28 -preset medium -pix_fmt yuv420p -movflags +faststart h264.mp4
gst-launch-1.0 -v filesrc location=edu111-orig.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc control-rate=0 bitrate=1000000 peak-bitrate=6500000 iframeinterval=100 ratecontrol-enable=0 quant-i-frames=30 quant-p-frames=30 quant-b-frames=30 preset-level=4 MeasureEncoderLatency=1 profile=0 ! h265parse ! qtmux ! filesink location=buka-nvv4l2decoder-nvv4l2h265enc.mp4
【推荐这个参数列表】 ```bash gst-launch-1.0 -v filesrc location=edu111-orig.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc ! h265parse ! qtmux ! filesink location=buka-nvv4l2decoder-nvv4l2h265enc-no-args.mp4 (这个命令是可以简化的最简形式,转码后的文件相当大) gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h264enc control-rate=0 bitrate=1000000 peak-bitrate=6500000 iframeinterval=100 ratecontrol-enable=0 quant-i-frames=30 quant-p-frames=30 quant-b-frames=30 preset-level=4 MeasureEncoderLatency=1 profile=0 ! h264parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2h264enc.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc control-rate=0 bitrate=1000000 peak-bitrate=6500000 iframeinterval=100 ratecontrol-enable=0 quant-i-frames=30 quant-p-frames=30 quant-b-frames=30 preset-level=4 MeasureEncoderLatency=1 profile=0 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2h265enc.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc iframeinterval=100 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-i-frame-100.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc iframeinterval=30 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-i-frame-30.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc control-rate=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-vbr.mp4 (Control-rate-1:VBR, 0:disable, 2:CBR, 3:Variable bit rate with frame skip. The encoder skips frames as necessary to meet the target bit rate.,4:Constant bit rate with frame skip) (Control-rate-1:VBR, 0:disable, 2:CBR, 3:Variable bit rate with frame skip. The encoder skips frames as necessary to meet the target bit rate.,4:Constant bit rate with frame skip) gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc control-rate=1 bitrate=6000000 peak-bitrate=6500000 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-cr3.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc qp-range="10,30:10,35:10,35" ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-qp-range.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc preset-level=0 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-present-level.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc preset-level=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-present-level.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc profile=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-profile_1.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc insert-sps-pps=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-insert-sps-pps.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc EnableTwopassCBR=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-twopasscbr.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc slice-header-spacing=8 bit-packetization=0 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-slice-header.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc slice-header-spacing=1400 bit-packetization=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-slice-header-1400.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc insert-sps-pps=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-insert-sps-pps.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc EnableTwopassCBR=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-nvv4l2-twopasscbr.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc slice-header-spacing=8 bit-packetization=0 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-slice-header.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc slice-header-spacing=1400 bit-packetization=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-slice-header-1400.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc insert-aud=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-insert-aud.mp4 gst-launch-1.0 -v filesrc location=edu10-03.mp4 ! qtdemux name=demux demux.video_0 ! queue ! h264parse ! nvv4l2decoder ! nvv4l2h265enc insert-vui=1 ! h265parse ! qtmux ! filesink location=test-nvv4l2decoder-insert-vui.mp4 ```
文件 大小 原格式 - 分辨率 转码格式 转码后后大小 转码时间 命令 评价
edu111-orig.mp4 1956KB h264 h265 1056KB 0.836s 1
edu111-orig.mp4 1956KB h264 h265 4180KB 0.700s 2
edu10-03.mp4 184MB h264 2K h264 2K 58MB 0:06:30 3 文字有失真
edu10-03.mp4 184MB h264 2k h265 2k 53MB 0:12:13 4 文字有失真
edu10-03.mp4 184MB h264 2k h265 2k 243MB 0:02:21 5 卡顿
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:02:21 6 卡顿(I帧影响运行)
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:02:21 7
edu10-03.mp4 184MB h264 2k h265 2k 373MB 0:02:01 8
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:58 9
edu10-03.mp4 184MB h264 2k h265 2k 244MB 0:02:09 10
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:58 11
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:58 12
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:57 13
edu10-03.mp4 184MB h264 2k h265 2k 328MB 0:03:33 14
edu10-03.mp4 184MB h264 2k h265 2k 266MB 0:02:37 15 有闪屏
edu10-03.mp4 184MB h264 2k h265 2k 252MB 0:01:57 16
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:57 13
edu10-03.mp4 184MB h264 2k h265 2k 328MB 0:03:33 14
edu10-03.mp4 184MB h264 2k h265 2k 266MB 0:02:37 15 有闪屏
edu10-03.mp4 184MB h264 2k h265 2k 252MB 0:01:57 16
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:55 21
edu10-03.mp4 184MB h264 2k h265 2k 247MB 0:01:55 22
Nvidia 硬件编码参数及含义():
名称 参考命令含义 参考命令
I-Frame Interval 全帧中I帧的间距,不宜太大。对运动画面影响较大,数值越小,文件越大。
temporal-tradeoff 人为强制丢弃帧,以5帧内为单位。Not Supported
control-rate 0: disable,1: variable bit rate,2: CBR, 3:Variable bit rate with frame skip, 4: Constant bit rate with frame skip
peak bitrate
指定bitrate的一个范围,默认的最大值是平均值的1.2倍。
Set Quantization Range for I, P and B Frame qp-range="10,30:10,35:10,35": [0:51] for I, P和B帧
Set Hardware Preset Level
0:UltraFastPreset,1:FastPreset,2:MediumPreset,3:SlowPreset
值越大,体积越大
Set Profile 1: Baseline profile, 2:Main profile(Not Used)(Not Used), 8: High profile(Not used)(Not used)
num-B-Frames
254enc not supported
insert-sps-pps a sequence parameter set (SPS) and a picture parameter set (PPS) are inserted before each IDR frame in the H.264/H.265 stream(具体作用还未清晰)
Two-Pass CBR Two-pass CBR must be enabled along with constant bit rate (control-rate=2)
slice-header-spacing=8 bit-packetization=0 The parameter bit-packetization=0 configures the network abstraction layer (NAL) packet as macroblock (MB)-based, and slice-header-spacing=8 configures each NAL packet as 8 MB at maximum. 15
slice-header-spacing=1400 bit-packetization=1
16
num-B-Frames
254enc not supported
insert-sps-pps a sequence parameter set (SPS) and a picture parameter set (PPS) are inserted before each IDR frame in the H.264/H.265 stream(具体作用还未清晰)
Two-Pass CBR Two-pass CBR must be enabled along with constant bit rate (control-rate=2)
slice-header-spacing=8 bit-packetization=0 The parameter bit-packetization=0 configures the network abstraction layer (NAL) packet as macroblock (MB)-based, and slice-header-spacing=8 configures each NAL packet as 8 MB at maximum. 15
slice-header-spacing=1400 bit-packetization=1 The parameter bit-packetization=1 configures the network abstraction layer (NAL) packet as size-based, and slice-header-spacing=1400 configures each NAL packet as 1400 bytes at maximum. 16
cabac-entropy-coding=1 H265 Not Supported
EnableMVBufferMeta This property enables motion vector metadata for encoding (long long time)
insert-aud This property inserts an H.264/H.265 Access Unit Delimiter (AUD) 21
insert-vui Usability Information (VUI) in SPS 22
poc-type
0: POC explicitly specified in each slice header (the default)
2: Decoding/coding order and display order are the same
only 264