学习多媒体系列教程(从最基础的C语法->编写实用的C++播放器->前沿音视频处理技术)
使用的操作系统 Ubuntu 18.10
编译器 gcc (Ubuntu 8.2.0-7ubuntu1) 8.2.0
集成开发环境 CLion 2018.3.4
管理 CMake
邮件讨论 wangrl2016@gmail.com
主要讲指针,内存管理,和文件读写等C高级操作。
参考《Pointers On C》写的部分代码示例。
字符串的输入输出处理。
注:跳过语法,函数,数组,指针基础章节。
主要讲结构体,初始化,和结构体指针。
分配void* malloc(size_t size);
释放void free(void *pointer);
通过链表来介绍结构体和指针知识。
如果需要修改指针的指向,需要传递双重指针,因为指针在函数中也是按值传递。
- 下载源码
git clone https://github.com/FFmpeg/FFmpeg
- ./configure
进行配置,可以通过
./configure --help
进行查看。
--enable-shared
编译动态库。 make
&&sudo make install
头文件在/usr/local/include/目录下面,生成库文件在/usr/local/lib/目录下面。
主要库文件
libavcodec
encoding/decoding library
libavfilter
graph-based frame editing library
libavformat
I/O and muxing/demuxing library
libavdevice
special devices muxing/demuxing library
libavutil
common utility library
libswresample
audio resampling, format conversion and mixing
libpostproc
post processing library
libswscale
color conversion and scaling library
牢记上面这张图,接下来的部分都会围绕这张图展开,其中很重要的几个概念,Demuxer, Muxer, Packet, Frame, Decoder, Encoder,后续后详
细介绍。先介绍命令行的使用,然后开始编写代码,需要的资源文件在res/目录下面。
主要熟悉FFmpeg的功能
ffmpeg终端语法规则
ffmpeg [global options] [input file options] -i input_file [output file options] output_file
ffmpeg -f lavfi -i rgbtestsrc -pix_fmt yuv420p -f sdl Example
输出视频并调用sdl显示。
ffplay -f lavfi -i testsrc -vf transpose=1
ffmpeg -i input.mp3 -af atempo=0.8 output.mp3
-vf表示video filters, -af表示audio filters.
ffmpeg -h decoder=flv
ffmpeg -codecs
ffmpeg -filters
ffmpeg -formats
ffmpeg -protocols
ffmpeg -i input.avi -r 30 output.mp4 指定帧率
video_size = video_bitrate * time_in_seconds / 8
audio_size = sampling_rate * bit_depth * channels * time_in_seconds / 8
ffmpeg -i input.avi -s vga output.avi
指定播放尺寸 640x480
ffmpeg -i input.mpg -vf scale=iw0.9:ih0.9 output.mp4
ffmpeg -f lavfi -i testsrc -vf crop=29:52:256:94 -t 10 timer1.mpg
相对左上原点的距离加上输出视频的长和宽。
ffmpeg -i input -vf pad=iw:iw*3/4:0:(oh-ih)/2:color output
将视频从16:9转化为4:3
ffplay -f lavfi -i rgbtestsrc -vf vflip
视频转置
ffmpeg -i CMYK.avi -vf transpose=1 CMYK_transposed.avi 顺时针转90度
ffmpeg -i halftone.jpg -vf smartblur=5:0.8:0 blurred_halftone.png 模糊处理
ffmpeg -i input.mpg -vf mp=denoise3d output.webm
锐化
ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w:H-h pair3.mp4
覆盖,图片显示在右下角。
添加文字
ffmpeg -i input.avi -ss 10 output.mp4
设置开始时间
ffplay -f lavfi -i aevalsrc=cos(523.2512PI*t)
余弦函数
元数据通过-metadata指定
ffmpeg -i video.avi -vf subtitles=titles.srt video.mp4
ffmpeg -i videoclip.avi -ss 01:23:45 image.jpg
截取视频帧保存为图片
ffmpeg -i image.png -vf transpose=1 image_rotated.png
ffmpeg -f image2 -i img%d.jpg -r 25 video.mp4
从图片中合成视频
ffmpeg -f lavfi -i aevalsrc=sin(4402PI*t) -t 10 noteA4.mp4
声音合成
ffmpeg -i stereo.wav -af pan=mono mono.wav
双声道变成单声道
ffmpeg -i music.mp3 -af earwax -q 1 music_headphones.mp3
增强耳机效果
使用预置文件
vcodec=libx264
vprofile=baseline
level=13
maxrate=768000
bufsize=3000000
扫描方式
FFplay FFprobe FFmpeg
libavcodec libavdevice libavfilter libavformat libavutil libpostproc libswresample libswscale
音视频录制
Bash
ffplay -f lavfi -i smptebars -vf lutyuv=u=128:v=128
黑白
ffplay -f lavfi -i rgbtestsrc -vf lutrgb=r=0:g=0
过滤红色和绿色
yuv格式
音视频连接
concatenation merge(相对于音频流) mix(相对于channel) multiplex overlay
ffmpeg -i input1.avi -i input2.avi -filter_complex concat output.mp4
ffmpeg -i eagles.mpg -vf delogo=x=730:y=0:w=70:h=46:t=1 nologo.mpg
移除logo
ffmpeg -i travel.avi -vf deshake fixed_travel.avi
消除抖动
ffmpeg -i ship.avi -vf drawbox=x=150:w=600:h=400:c=yellow ship1.avi
增加颜色框
ffmpeg -i audio.mp3 -vf showspectrum audio_spectrum.mp4
音频光谱
Festival Speech Synthesis System
语音合成引擎
详细解释都在代码注释中。
metadata.c
读取文件的元数据输出。
调用avformat_open_input函数构造AVFormatContext结构体,相当于Android中的Context角色,提供编解码过程中需要的各种资源。 访问AVDictionary* AVFormatContext::metadata属性,通过while循环不断查询获取metadata的key和value值。decode_video.c
解码视频的前几帧,保存为灰度图片。
构建AVFormatContext结构体,轮询视频文件中的流信息,使用查询到的视频流构建AVCodecContext。然后创建AVFrame和AVPacket,通过 avcodec_send_packet函数将将视频数据送到AVPacket中,通过avcodec_receive_frame函数传递到AVFrame中,最终写入到文件。encode_video.c
MPEG4编码2秒钟的视频,可以使用播放器播放。
通过avcodec_find_encoder构造AVCodec,进而构造AVCodecContext,然后传入参数对AVCodecContext进行设置,比如视频编码格式,宽和高等。 构建AVPacket和AVFrame结构体,向AVFrame中填充YUV数据,通过avcodec_send_frame和avcodec_receive_packet函数将数据传递到AVPacket中, 最终AVPacket写入到文件中。scaling_video.c
通过sws_scale函数转换视频的尺寸。
将生成的的帧图片转换存入到另外的文件中。filtering_video.c
改变视频的尺寸和转置90度从终端输出。
和decode_video.c
相同的处理获取Frame,然后通过avfilter_graph_create_filter构建两个filter,函数av_buffersrc_add_frame_flags 表示输入到filter中,函数av_buffersink_get_frame表示从filter中输出。hw_decode.c
硬件加速。
解码过程和decode_video.c
类似,添加av_hwdevice_ctx_create函数创建AVBufferRef指针。demuxing.c
一种视频格式转换为另外一种视频格式。 通过输入输出文件的后缀创建相应的Context,转换对应的packet,最终写入到输出文件中。transcoding.c
demuxing, decoding, filtering, encoding and muxing 连续操作。
注: 协议解读是html文件,需要下载下来使用浏览器打开。
Bootstrap Documentation
很fashion的前端库,方便写html网页。
主要是Bootstrap的Layout, Content, Components, Utilities示例。
Portable Network Graphics (PNG) Specification (Second Edition)
samples, channels, pixels, and sample depth之间的关系
编码流程PNG image -> Pass extraction -> Scanline serialization -> Filtering -> Compression -> Chunking -> Datastream construction
PNG数据流由一系列的chunks构造,重要的四个
IHDR
文件头PLTE
palette表IDAT
数据chunksIEND
文件结束
详细介绍查看网页PNG协议解读
WebP协议
编译
make -f makefile.unix
./autogen.sh
./configure --enable-everything
make
sudo make install
后续写实现
示例参考cppreference官网
unique_ptr_test.cpp
通过make_unique创建对象,通过move进行对象的转移,只允许一个指针拥有该对象实例。
shared_ptr_test.cpp
多个指针可以指向同一个对象,对象的引用计数use_count增加。
weak_ptr_test.cpp
不会引起use_count的增加。
allocator_test.cpp
分配内存
lvalue_rvalue_test.cpp
左值引用和右值引用
右值引用延长临时变量的生命周期,可以简单地理解为左值可以取地址,右值不能取地址。
https://www.cnblogs.com/qicosmos/p/4283455.html
SFML的安装sudo apt-get install libsfml-dev
测试代码 sfml/examples/SFMLTest.cpp
以Introduction to Algorithms
为蓝本学习算法。
算法笔记,代码也在对应文件夹。
- The Role of Algorithms in Computing
- Getting Started
- Growth of Functions
- Divide-and-Conquer
- Probabilistic Analysis and Randomized Algorithms
- Heapsort
- Quicksort
- Sorting in Linear Time
- Medians and Order Statistics
- Elementary Data Structures
- Hash Tables
- Binary Search Trees
- Red-Black Trees
- Augmenting Data Structures
- Dynamic Programming
- Greedy Algorithms
- Amortized Analysis
- B-Trees
- Fibonacci Heaps
- van Emde Boas Trees
- Data Structures for Disjoint Sets
- Elementary Graph Algorithms
- Minimum Spanning Trees
- Single-Source Shortest Paths
- All-Pairs Shortest Paths
- Maximum Flow
- Multithreaded Algorithms
- Matrix Operations
- Linear Programming
- Polynomials and the FFT
- Number-Theoretic Algorithms
- String Matching
- Computational Geometry
- NP-Completeness
- Approximation Algorithms
在需要传递的数据后面加上一串数据,这串数据是对需要传递的数据进行计算得到的,通过比较加上的数据验证传递的数据是否正确。
crc实现
详细的解释查看
A Painless Guide to CRC Error Detection Algorithms
将java-design-patterns改写成C++的实现方式。
具体的分析在soft_framework/design_patterns目录。
使用CMakeLists.txt进行重写,实现最基础的功能,不用考虑跨平台,也不用考虑优化等。
CommandLineFlags.cpp
skia_test.cpp 测试入口
所有函数实现公共类都要进行测试,
Leetcode官网的答案在leetcode文件夹。
都已经通过测试,而且大部分都是最优解,结合算法导论会理解更深刻。
数组非常常见。
hash = hashfunc(key)
index = hash % array_size
程序不断调用本身,传递不同的参数,同时需要有结束条件。