从mpeg ts文件中提取I帧(7):程序的编译运行
一、工程目录
├── img //保存的各种文件
│ ├── 0112.bmp
│ ├── 0112.pes
│ ├── 0112.rgb
│ ├── 0112.yuv
├── makefile //编译脚本
├── objs //编译过程的中间件文件
│ ├── cvshow.d
│ ├── cvshow.i
│ ├── cvshow.o
│ ├── ffdecode.d
│ ├── ffdecode.i
│ ├── ffdecode.o
│ ├── iframe.out
│ ├── main.d
│ ├── main.i
│ ├── main.o
│ ├── mpegpes.d
│ ├── mpegpes.i
│ ├── mpegpes.o
│ ├── mpegpsi.d
│ ├── mpegpsi.i
│ ├── mpegpsi.o
│ ├── mpegtsp.d
│ ├── mpegtsp.i
│ └── mpegtsp.o
├── src //源码
│ ├── cvshow.cpp
│ ├── cvshow.h
│ ├── ffdecode.c
│ ├── ffdecode.h
│ ├── main.c
│ ├── mpegpes.c
│ ├── mpegpes.h
│ ├── mpegpsi.c
│ ├── mpegpsi.h
│ ├── mpegtsp.c
│ ├── mpegtsp.h
│ └── xdebug.h
二、ffmpeg要求完成一次完整的编译
如果要调试 configure 加参数 --disable-optimizations disable compiler optimizations
否则单步时gdb会乱跳一通。
三、opencv要求完成一次完整的编译
注意事项:
1、opencv编译时回去下载ippicv,过程比较慢,容易超时。
在 opencv-3.4.0/cmake/OpenCVDownload.cmake这个文件里可以修改超时时间。
下载的文件缓存在这里:
/work/sde/opencv/opencv-3.4.0/.cache/ippicv
4e0352ce96473837b1d671ce87f17359-ippicv_2017u3_lnx_intel64_general_20170822.tgz
2、编译
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/work/sdb/opensrc/opencv/out
make -j8
make install
3、设置pkgconfig
export PKG_CONFIG_PATH=/work/sde/opencv/out/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH
可以添加到开机启动脚本里 /etc/profile
4、配置动态库路径
vim /etc/ld.so.conf.d/opencv.conf
/work/sdb/opensrc/opencv/out/lib/x86_64-linux-gnu
ldconfig
5、遇到一个编译错误 ImfChromaticities.h: No such file or directory
apt-get install libopenexr-dev
二、makefile
CC = gcc
CX = g++
CP = cp
MV = mv
RM = -rm -rf
JB = ${shell cat /proc/cpuinfo | grep "processor" | wc -l}
FFMPEG = /work/sdb/opensrc/ffmpeg/ffmpeg-3.0.0
FFLIBS = $(FFMPEG)/libavformat/libavformat.a \
$(FFMPEG)/libavcodec/libavcodec.a \
$(FFMPEG)/libavutil/libavutil.a \
$(FFMPEG)/libavdevice/libavdevice.a \
$(FFMPEG)/libavfilter/libavfilter.a \
$(FFMPEG)/libswresample/libswresample.a \
$(FFMPEG)/libswscale/libswscale.a
CVLIBS = ${shell pkg-config opencv --libs}
SDIR = src
ODIR = objs
SRCS = main.c ffdecode.c cvshow.c mpegtsp.c mpegpes.c mpegpsi.c
LIBS = $(FFLIBS) $(CVLIBS) -lm -lpthread -lrt -lz -ldl
OBJS = $(addprefix $(ODIR)/, $(patsubst %.c, %.o, $(filter %.c, $(SRCS))) $(patsubst %.cpp, %.o, $(filter %.cpp, $(SRCS))))
DEPS = $(addprefix $(ODIR)/, $(patsubst %.c, %.d, $(filter %.c, $(SRCS))) $(patsubst %.cpp, %.d, $(filter %.cpp, $(SRCS))))
PRES = $(addprefix $(ODIR)/, $(patsubst %.c, %.i, $(filter %.c, $(SRCS))) $(patsubst %.cpp, %.i, $(filter %.cpp, $(SRCS))))
TARGET = $(ODIR)/iframe.out
INCDIR = -I./ -I$(FFMPEG) ${shell pkg-config opencv --cflags}
CFLAGS = -g -Wall -c
LFLAGS =
.PHONY: all clean $(ODIR)
all: $(ODIR) $(TARGET)
$(TARGET): $(OBJS) $(PRES)
@echo LD aaa@qq.com
@$(CX) $(LFLAGS) $(OBJS) $(LIBS) -o aaa@qq.com
@$(CP) aaa@qq.com ./
$(ODIR)/%.i: $(SDIR)/%.cpp
@$(CX) $(CFLAGS) -E $(INCDIR) -o aaa@qq.com $<
$(ODIR)/%.o: $(SDIR)/%.cpp
@echo CX $<
@$(CX) $(CFLAGS) -MMD -MP $(INCDIR) -o aaa@qq.com $<
$(ODIR)/%.i: $(SDIR)/%.c
@$(CC) $(CFLAGS) -E $(INCDIR) -o aaa@qq.com $<
$(ODIR)/%.o: $(SDIR)/%.c
@echo CC $<
@$(CC) $(CFLAGS) -MMD -MP $(INCDIR) -o aaa@qq.com $<
-include $(DEPS)
$(ODIR):
@test -d aaa@qq.com || mkdir -p aaa@qq.com
clean:
@$(RM) $(ODIR)
@echo RM $(ODIR)
对这个makefile的进一步理解请参考:https://blog.csdn.net/maxzero/article/details/52935482
1、ffmpeg采用静态链接,修改makefile中变量FFMPEG即可。
2、opencv采用pkgconfig的方式,配置好环境变量PKG_CONFIG_PATH即可。
三、程序的运行
1、帮助信息
./iframe.out -h
usage : iframe --file=xxx.ts --pid=0x101 --save=1
--file : mpeg2 ts file path
--pid : mpeg2 video pid
--index: iframe index
--save : 1-save file pes yuv bmp rgb. 0-nothing
--psi : only analyze pat pmt
2、显示psi信息
./iframe.out --file=/mnt/hgfs/wind/media/ts/506000.ts --psi
use params is:
--file_name=/mnt/hgfs/wind/media/ts/506000.ts
--file_save=0
--------pid=0x1fff(8191)
--------inc=1
--------psi=1
[src/main.c:0381] main() transport packet size=204
[src/main.c:0382] main() start position=0
pat section pid=0x0000
|-table_id =0x0
|-section_syntax_indicator=0x1
|-section_length =0x25
|-extend_table_id =0x2
|-version_number =0x1
|-current_next_indicator =0x1
|-section_number =0x0
|-last_section_number =0x0
|-program_number=0x0000 program_map_pid=0x0010 (16)
|-program_number=0x00c9 program_map_pid=0x0100 (256)
|-program_number=0x00ca program_map_pid=0x0200 (512)
|-program_number=0x00cb program_map_pid=0x0300 (768)
|-program_number=0x00cc program_map_pid=0x0400 (1024)
|-program_number=0x00cd program_map_pid=0x0500 (1280)
|-program_number=0x00ce program_map_pid=0x0600 (1536)
|-crc_32 = 0x6012d6e2 0x6012d6e2
pmt section pid=0x0100(256)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x4f
|-program_number = 0xc9
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x1ffe
|-program_info_length = 0x17
|+descriptor
|-unknown_descriptor tag=0x0b len=0x2 4a 1f
|-unknown_descriptor tag=0x0c len=0x4 80 b4 81 68
|-unknown_descriptor tag=0x0e len=0x3 c0 1e c6
|-unknown_descriptor tag=0x10 len=0x6 c0 1e c6 c0 08 00
|+es_pid = 0x101 stream_type = 0x2
|-unknown_descriptor tag=0x02 len=0x3 1a 48 5f
|-unknown_descriptor tag=0x52 len=0x1 00
|-unknown_descriptor tag=0x0e len=0x3 c0 1c f0
|-unknown_descriptor tag=0x06 len=0x1 02
|+es_pid = 0x102 stream_type = 0x4
|-unknown_descriptor tag=0x03 len=0x1 67
|-unknown_descriptor tag=0x0a len=0x4 65 6e 67 00
|-unknown_descriptor tag=0x52 len=0x1 8a
|-unknown_descriptor tag=0x0e len=0x3 c0 01 68
|-crc_32 = 0x580343a4 0x580343a4
pmt section pid=0x0200(512)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x4f
|-program_number = 0xca
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x1ffe
|-program_info_length = 0x17
|+descriptor
|-unknown_descriptor tag=0x0b len=0x2 4a 1f
|-unknown_descriptor tag=0x0c len=0x4 80 b4 81 68
|-unknown_descriptor tag=0x0e len=0x3 c0 1e c6
|-unknown_descriptor tag=0x10 len=0x6 c0 1e c6 c0 08 00
|+es_pid = 0x201 stream_type = 0x2
|-unknown_descriptor tag=0x02 len=0x3 1a 48 5f
|-unknown_descriptor tag=0x52 len=0x1 01
|-unknown_descriptor tag=0x0e len=0x3 c0 1c f0
|-unknown_descriptor tag=0x06 len=0x1 02
|+es_pid = 0x202 stream_type = 0x4
|-unknown_descriptor tag=0x03 len=0x1 67
|-unknown_descriptor tag=0x0a len=0x4 65 6e 67 00
|-unknown_descriptor tag=0x52 len=0x1 94
|-unknown_descriptor tag=0x0e len=0x3 c0 01 68
|-crc_32 = 0x315d6826 0x315d6826
pmt section pid=0x0300(768)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x1a
|-program_number = 0xcb
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x301
|-program_info_length = 0x0
|+es_pid = 0x301 stream_type = 0x2
|-unknown_descriptor tag=0x11 len=0x1 ff
|-es_pid = 0x302 stream_type = 0x3
|-crc_32 = 0x4bbb50a7 0x4bbb50a7
pmt section pid=0x0400(1024)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x1a
|-program_number = 0xcc
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x401
|-program_info_length = 0x0
|+es_pid = 0x401 stream_type = 0x2
|-unknown_descriptor tag=0x11 len=0x1 ff
|-es_pid = 0x402 stream_type = 0x3
|-crc_32 = 0x766fc8c7 0x766fc8c7
pmt section pid=0x0500(1280)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x1f
|-program_number = 0xcd
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x501
|-program_info_length = 0x5
|+descriptor
|-unknown_descriptor tag=0x0e len=0x3 c0 3b ab
|+es_pid = 0x501 stream_type = 0x2
|-unknown_descriptor tag=0x06 len=0x1 02
|-es_pid = 0x502 stream_type = 0x4
|-crc_32 = 0x21864701 0x21864701
pmt section pid=0x0600(1536)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x1f
|-program_number = 0xce
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x601
|-program_info_length = 0x5
|+descriptor
|-unknown_descriptor tag=0x0e len=0x3 c0 38 a4
|+es_pid = 0x601 stream_type = 0x2
|-unknown_descriptor tag=0x06 len=0x1 02
|-es_pid = 0x602 stream_type = 0x4
|-crc_32 = 0xfbb2eb1a 0xfbb2eb1a
3、显示一幅指定的I并保存相关文件
显示视频pid=0x201的第20副I帧
./iframe.out --file=/mnt/hgfs/wind/media/ts/506000.ts --pid=0x201 --index=20 --save=1
运行效果图:
全文完!
mpeg2标准:https://download.csdn.net/download/maxzero/10402761
完整的代码:https://download.csdn.net/download/maxzero/10572383