欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从mpeg ts文件中提取I帧(7):程序的编译运行

程序员文章站 2022-07-14 21:37:58
...

一、工程目录

├── 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
运行效果图:
从mpeg ts文件中提取I帧(7):程序的编译运行

全文完!

mpeg2标准:https://download.csdn.net/download/maxzero/10402761
完整的代码:https://download.csdn.net/download/maxzero/10572383