windows 使用qt mingw730_64 编译ffmpeg

2022-4-10 C++

下载ffmpeg源码:https://www.ffmpeg.org/download.html

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg

1. 安装MSYS2

    到https://www.msys2.org/下载最新的MSYS2安装包,一路next

2. 安装完成后启动MSYS2 MinGW x64

3. 安装make yasm diffutils pkg-config工具

pacman -S make yasm diffutils pkg-config

如因网络问题安装不上则修改c:\msys64\etc\pacman.d\mirrorlist.mingw64把tsinghua的源移到第一行

如Server=https://mirrors.tuna.stsinghua.edu.cn/msys2/mingw/x86_64

之后输入pacman -Sy重新加载下

4. 添加qtmingw730bin进PATH

如export PATH=/d/Qt/Qt5.14.2/Tools/mingw730_64/bin:$PATH

5. 配置ffmpeg如

./configure --enable-shared --arch=x86_64 --prefix=/d/ffmpeg/install

6. 之后就是make;make install等待编译完成

标签: ffmpeg qt mingw

评论(0) 浏览(11835)

Windows平台webRTC编译

2022-4-7

1. Visual Studio安装

选择最新的vs2022,用的是社区版,安装时选择自定义安装

a)勾选使用C++的桌面开发

b)  Windows 10 SDK安装10.0.20348.0 取消10.0.1904.0

c)勾选MFC及ATL这两项

d) 安装完VS2022后,必须安装sdk调试工具。打开控制面板->程序与功能,找到Windows Software Development Kit, 点更改

勾选Debugging Tools For Windows

2. 安装depot_tools

从https://storage.googleapis.com/chrome-infra/depot_tools.zip下载depot_tools安装后,解压到电脑任一位置,并把depot_tools目录的路径加到系统环境变量Path里

3. 获取WebRtc源码

a) 需要代理

b)打开cmd窗口,输入gclient安装必须工具

c)设置环境临时变量如

set vs2022_install=C:\Program Files\Microsoft Visual Studio\2022\Community
set GYP_MSVS_OVERRIDE_PATH=C:\Program Files\Microsoft Visual Studio\2022\Community
set GYP_GENERATORS=msvs-ninja,ninja
set WINDOWSSDKDIR=C:\Program Files (x86)\Windows Kits\10
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
set GYP_MSVS_VERSION=2022
d) 创建webrtc源码存放目录,并获取webrtc(编译完大概占用23g的电脑空间)

mkdir d:\webrtc

cd d:\webrtc

fetch --nohooks webrtc

gclient sync

3.编译工程

编译生成release版本

cd d:\webrtc\src

gn gen out/Default --ide=vs2022 --sln=webrtc --args="use_lld=false is_debug=false"

4.参考

https://webrtc.github.io/webrtc-org/native-code/development/

5. 编译遇到的问题:

a)环境变量含中文导致写环境变量失败

UnicodeEncodeError: 'gbk' codec can't encode character '\u04e2' in position 3840: illegal multibyte sequence

修改src\build\toolchain\win\setup_toolchain.py

    f.write(env_block.encode('utf-8').decode('GBK'))

b) lld-link: error: procedure symbol record for `operator new` 

   添加参数use_lld=false 



标签: webrtc vs2022

评论(0) 浏览(1006)

centos 7 python pyinstaller pyqt4 打包环境

2022-2-24

1. 参考https://gist.github.com/chappyhome/7595706安装

注意:

    1. 编译python要动态编译,不然pyinstaller打包会有问题

    ./configure --prefix=/usr/local --enable-shared LDFLAGS=-Wl,-rpath=/usr/local/lib

    2. pyinstaller 4.0版本有问题,可以装3.6

    python -m pip install PyInstaller==3.6

    3. vlc运行环境配置

    export PYTHON_VLC_MODULE_PATH=/usr/lib64/vlc/plugins

标签: pyinstller pyqt4 pyinstaller vlc

评论(0) 浏览(1436)

python flask 上传大文件如1G以上 413错误解决

2022-2-12 python

生产环境:flask waitress

在flask项目中,上传超过1GB文件时后台报http 413 Request Entity Too Large 请求体太大错误!

解决方法:

1. 修改adjustments.py的max_request_body_size

  如设置max_request_body_size=1073741824*5,则小于5G的文件都能上传之后到MAX_CONTENT_LENGTH再判断

2.在flask配置中设置 MAX_CONTENT_LENGTH的值;

   如设置为2G ( MAX_CONTENT_LENGTH=2*1024*1024*1024)  这时小于20M的文件都可以上传

标签: python flask large file upload

评论(0) 浏览(1800)

T3 配置 lvds 点屏

2021-9-26 C++

T3通过配置操作可以实现lvds 配置的修改,实现点屏。

主要问题是:vesa模式与jeida模式

;lcd_lvds_mode:        0:NS mode; 1:JEIDA mode
;lcd_lvds_ab_reverse:  0: not reverse; 1:reverse

vesa 屏调试后点屏啥都OK,换乘jeida屏后,出现了重影,通过调整ab线解决该问题。

看网上其他的芯片都可以通过配置更改ab线极性,通过查看芯片数据手册,全志没做特别说明(有点坑)。

通过咨询代理,更改tcon0_lvds_even_odd_dir可以实现极性反转。

因此增加lcd_lvds_ab_reverse配置,之后就可以通过更改屏参解决ab线反转。

;----------------------------------------------------------------------------------
;lcd0 configuration

;lcd_if:               0:hv(sync+de); 1:8080; 2:ttl; 3:lvds; 4:dsi; 5:edp; 6:extend dsi
;lcd_x:                lcd horizontal resolution
;lcd_y:                lcd vertical resolution
;lcd_width:            width of lcd in mm
;lcd_height:           height of lcd in mm
;lcd_dclk_freq:        in MHZ unit
;lcd_pwm_freq:         in HZ unit
;lcd_pwm_pol:          lcd backlight PWM polarity
;lcd_pwm_max_limit     lcd backlight PWM max limit(<=255)
;lcd_hbp:              hsync back porch
;lcd_ht:               hsync total cycle
;lcd_vbp:              vsync back porch
;lcd_vt:               vysnc total cycle
;lcd_hspw:             hsync plus width
;lcd_vspw:             vysnc plus width
;lcd_lvds_if:          0:single link;  1:dual link
;lcd_lvds_colordepth:  0:8bit; 1:6bit
;lcd_lvds_mode:        0:NS mode; 1:JEIDA mode
;lcd_lvds_ab_reverse:  0: not reverse; 1:reverse
;lcd_frm:              0:disable; 1:enable rgb666 dither; 2:enable rgb656 dither
;lcd_io_phase:         0:noraml; 1:intert phase(0~3bit: vsync phase; 4~7bit:hsync phase;
;                      8~11bit:dclk phase; 12~15bit:de phase)
;lcd_gamma_en          lcd gamma correction enable
;lcd_bright_curve_en   lcd bright curve correction enable
;lcd_cmap_en           lcd color map function enable
;deu_mode              0:smoll lcd screen; 1:large lcd screen(larger than 10inch)
;lcdgamma4iep:         Smart Backlight parameter, lcd gamma vale * 10;
;                      decrease it while lcd is not bright enough; increase while lcd is too bright
;smart_color           90:normal lcd screen 65:retina lcd screen(9.7inch)
;----------------------------------------------------------------------------------
[lcd0]
lcd_used            = 1
lcd_driver_name     = "default_lcd"
lcd_backlight       = 128 
lcd_if              = 3
lcd_x               = 1920
lcd_y               = 1080 
lcd_width           =
lcd_height          =
lcd_dclk_freq       = 148
lcd_pwm_used        = 1
lcd_pwm_ch          = 0 
lcd_pwm_freq        = 300
lcd_pwm_pol         = 0
lcd_pwm_max_limit   = 255

lcd_ht              = 2200 
lcd_hbp             = 140
lcd_hspw            = 45 

lcd_vt              = 1125 
lcd_vbp             = 25 
lcd_vspw            = 5 

lcd_lvds_if         = 1
lcd_lvds_ch         = 1
lcd_lvds_colordepth = 0
lcd_lvds_mode       = 0
lcd_lvds_ab_reverse = 0
lcd_frm             = 0
lcd_hv_clk_phase    = 0
lcd_hv_sync_polarity= 0
lcd_gamma_en        = 0
lcd_bright_curve_en = 0
lcd_cmap_en         = 0

deu_mode            = 1
lcdgamma4iep        = 22
smart_color         = 90


标签: 全志 T3 ab线

评论(0) 浏览(2415)

python scrapy爬取XX基金

2020-12-23

需求:爬取XX基金的所有基金信息写入mongodb,同步到mysql并界面显示


标签: MFC python mongodb mysql

评论(0) 浏览(3732)

设计模式总结

2020-5-20 C++

一、创造型

1. 抽象工厂模式(Abstract Factory)

    a) 分离了具体的类

    b) 有利于产品的一致性

    c) 使得易于交换产品系列

    d) 难于支持新种类的产品(需要扩展接口就涉及到对所有子类的修改)

2. 生成器(Builder)

    a) 可以改变一个产品的内部表示(定义一个新的生成器)

    b) 将构建代码与表示代码分开

    c) 可对构建过程进行更精细的控制

3. 工厂方法(Factory Method)

    a) 为子类提供挂钩

    b) 连接平行的类层次


未完。。待续。。

标签: 设计模式

评论(0) 浏览(5263)

windows查看linux ext4内容

2020-5-19

需要工具:

 simg2img.exe:img提取工具

osfmount.exe:ext4文件系统挂载到windows

osfmount.exe下载地址:https://www.osforensics.com/tools/mount-disk-images.html

步骤:

1.simg2img.exe -i rootfs_256M.ext4 -o rootfs_256M.raw

2. osfmount.exe 挂载 rootfs_256M.raw

标签: windows ext4

评论(0) 浏览(3038)

C++解析TS流

2020-5-16

TS流格式见:https://blog.csdn.net/dxpqxb/article/details/79654004

协议文件见:iso13818-1.pdf
/********************************PAT PMT PES相关解析代码及结构体*******************************/
typedef unsigned char BYTE;
#define TS_PACKET_LENGTH 188
#define TS_SYNC_BYTE 0x47
#define TS_HEADER_SIZE 4

typedef enum _eStreamType
{
 TS_STREAM_TYPE_NULL = 0,
 TS_STREAM_TYPE_ADTS = 0xF, //具有ADTS音频
 TS_STREAM_TYPE_H264 = 0x1B //H.264格式
} TsStreamtype;

typedef struct _TsPtsDtsA
{
 BYTE marker1 : 1;
 BYTE pts30 : 3;
 BYTE res1 : 4; //1
 BYTE pts22;    //2
 BYTE marker2 : 1;
 BYTE pts15 : 7; //3
 BYTE pts7; //4
 BYTE marker3 : 1;
 BYTE pts0 : 7; //5
} TsPtsDtsA;

typedef struct _TsPtsDtsB
{
 BYTE marker1 : 1;
 BYTE pts30 : 3;
 BYTE res1 : 4; //1
 BYTE pts22;    //2
 BYTE marker2 : 1;
 BYTE pts15 : 7; //3
 BYTE pts7; //4
 BYTE marker3 : 1;
 BYTE pts0 : 7; //5
 BYTE marker4 : 1;
 BYTE dts30 : 3;
 BYTE res2 : 4; //6
 BYTE dts22;    //7
 BYTE marker5 : 1;
 BYTE dts15 : 7; //8
 BYTE dts7; //9
 BYTE marker6 : 1;
 BYTE dts0 : 7; //10
} TsPtsDtsB;

typedef struct _TsPes
{
 BYTE startCode[3]; //1 起始码 00 00 01
 BYTE streamId;    //4 0xe0
 BYTE pesLengthH;   //5
 BYTE pesLengthL;   //6
 BYTE originalOrCopy : 1;
 BYTE copyRight : 1;
 BYTE dataAlignmentIndicator : 1;
 BYTE pesPriority : 1;
 BYTE pesScramblingControl : 2;
 BYTE res1 : 2; //7
 BYTE pesExtensionFlag : 1;
 BYTE pesCrcFlag : 1;
 BYTE additionalCopyInfoFlag : 1;
 BYTE dsmTrickModeFlag : 1;
 BYTE esRateFlag : 1;
 BYTE escrFlag : 1;
 BYTE ptsDtsFlags : 2;   //8
 BYTE pesHeaderDataLength; //9
} TsPes;

typedef struct _TsPatProgram
{
 BYTE programNumberH;  //节目号
 BYTE programNumberL;  //节目号
 BYTE programMapPidH : 5; //节目PID
 BYTE res1 : 3;  //预留 默认111
 BYTE programMapPidL;  //节目PID
} TsPatProgram;

typedef struct _TsPat
{
 BYTE tsHeaderRes;  //预留错误码,固定为00
 BYTE tableId;  //固定为0x00 ,标志是该表是PAT
 BYTE sectionLengthH : 4;  //段长度
 BYTE reserved_1 : 2;  //保留
 BYTE zero : 1;  //无用
 BYTE sectionSyntaxIndicator : 1; //段语法标志位,固定为1
 BYTE sectionLengthL;  //段长度
 BYTE transportStreamIdH;  //该传输流的ID,区别于一个网络中其它多路复用的流
 BYTE transportStreamIdL;  //该传输流的ID,区别于一个网络中其它多路复用的流
 BYTE currentNextIndicator : 1;  //发送的PAT是当前有效还是下一个PAT有效
 BYTE versionNumber : 5;  //范围0-31,表示PAT的版本号
 BYTE reserved_2 : 2;  // 保留位11
 BYTE sectionNumber;  //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段
 BYTE lastSectionNumber;  //最后一个分段的号码
 TsPatProgram program;
 BYTE crc32[4]; //CRC32校验码
} TsPat;

typedef struct _TsNit
{
 BYTE tsHeaderRes;  //预留错误码,固定为00
 BYTE tableId;  //固定为0x00 ,标志是该表是PAT
 BYTE sectionLengthH : 4;  //段长度
 BYTE reserved_1 : 2;  //保留
 BYTE zero : 1;  //无用
 BYTE sectionSyntaxIndicator : 1; //段语法标志位,固定为1
 BYTE sectionLengthL;  //段长度
 BYTE transportStreamIdH;  //该传输流的ID,区别于一个网络中其它多路复用的流
 BYTE transportStreamIdL;  //该传输流的ID,区别于一个网络中其它多路复用的流
 BYTE currentNextIndicator : 1;  //发送的PAT是当前有效还是下一个PAT有效
 BYTE versionNumber : 5;  //范围0-31,表示PAT的版本号
 BYTE reserved_2 : 2;  // 保留位11
 BYTE sectionNumber;  //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段
 BYTE lastSectionNumber;  //最后一个分段的号码
 TsPatProgram program;
 BYTE crc32[4]; //CRC32校验码
} TsNit;

typedef struct _TsPmtProgram
{
 BYTE streamType;   //1 //类型 音频或视频
 BYTE elemPidH : 5; //2 //PID
 BYTE reseved1 : 3;
 BYTE elemPidL; //3
 BYTE esLengthH : 4; //内容长度
 BYTE reseved2 : 4; //4
 BYTE esLengthL; //5
} TsPmtProgram;

typedef struct _TsPmt
{
 BYTE tsHeaderRes;  //预留错误码,固定为00
 BYTE tableId;  //1 //不能是0xFF 固定为0x02表示是PMT
 BYTE sectionLengthH : 4;  //段长度
 BYTE reserved_1 : 2;  //保留
 BYTE zero : 1;  //无用
 BYTE sectionSyntaxIndicator : 1; //2 //段语法标志位,固定为1
 BYTE sectionLengthL;  //3 //段长度
 BYTE programNumberH;  //4 //节目
 BYTE programNumberL;  //5 //节目
 BYTE currentNextIndicator : 1;
 BYTE versionNumber : 5; //范围0-31,表示PMT的版本号
 BYTE reserved_2 : 2; //6 // 保留位11
 BYTE sectionNumber; //7 //分段号码
 BYTE lastSectionNumber; //8
 BYTE pcrPidH : 5;
 BYTE reverved_2 : 3; //9
 BYTE pcrPidL;  //10
 BYTE programInfoLengthH : 4;
 BYTE REVERVED_3 : 4;  //11
 BYTE programInfoLengthL; //12
 //descriptor
 TsPmtProgram pmtProgram;
 BYTE crc32[4]; //CRC32校验码
} TsPmt;

typedef struct _TsHeader
{
 BYTE syncByte; //同步码0x47
 BYTE pidH : 5; //Pid
 BYTE transportPriority : 1; //传输优先
 BYTE payloadUnitStartIndicator : 1; //有效负载 PUSI
 BYTE transportErrorIndicator : 1; //传输误码 TEI
 BYTE pidL; //pid
 BYTE continuityCounter : 4; //连续计数
 BYTE adaptionFieldControl : 2;
 //BYTE adaptionFieldControl:2; //自适应控制 00 01 10 11
 BYTE transportScramblingControl : 2; //传输加扰 TSC
 BYTE adaptionLength;  //自适应部分长度 当adaptionFieldExist 为1
  // Adaptation field when 10 11
  //payload data whe 01 11
} TsHeader;

static unsigned short MakeShort(unsigned char dataH, unsigned char dataL)
{
unsigned short num = 0;
num = dataH;
num <<= 8;
num |= dataL;
return num;
}

//传入1包数据(188)字节解析
int TsDemuxPacket(const unsigned char *pInputData, int tInputDataLen)
{
 if (pInputData == NULL || tInputDataLen != TS_PACKET_LENGTH)
 {
 printf("XYQ ==> ts data error !\n");
 return -1;
 }
 TsHeader *tsHeader = (TsHeader *)pInputData;
 if (tsHeader->syncByte != TS_SYNC_BYTE) // invalid packet sync byte
 {
 printf("XYQ ==> ts packet head error !\n");
 return -2;
 }

//解析Pat
static int TsDemuxPat(const unsigned char *pTempData, int tInputDataLen, bool bTempPayloadUnitStartIndicator)
{
 if (NULL == pTempData || tInputDataLen < sizeof(TsPat))
 {
 printf("XYQ ==> pat input data Error !\n");
 return -1;
 }
 TsPat *tsPat = (TsPat *)pTempData;
 if (bTempPayloadUnitStartIndicator != true)
 {
 printf("XYQ ==> pat payload indicator !\n");
 return -6;
 }
 if (tsPat->tableId != 0) //PAT tableId 固定为0
 {
 printf("XYQ ==> Is Not Pat !\n");
 return -7;
 }
 if (tsPat->sectionSyntaxIndicator != 0x01 && tsPat->reserved_1 != 0x03)
 {
 printf("XYQ ==> Pat section Syntax Error!\n");
 return -8;
 }

 unsigned short tTempLen = MakeShort(tsPat->sectionLengthH, tsPat->sectionLengthL);
 tInputDataLen -= 4;

 if (tTempLen > tInputDataLen) //剩余字节大小不小于pat内容长度
 {
 printf("XYQ ==> Pat table length Error! TempLen[%d] inputDataLen[%d]\n", tTempLen, tInputDataLen);
 return -9;
 }

 if (tsPat->currentNextIndicator != 1) //当前包是否有效
 {
 printf("XYQ ==> next valid!\n");
 return -10;
 }

 tTempLen -= (5 + 4); //标识符5个字节(暂无用)+4个字节校验码
 if ((tTempLen % 4) != 0)
 {
 printf("XYQ ==> Wrong Pat Data!\n");
 return -11;
 }

 int tTempNum = tTempLen / 4;
 pTempData = (unsigned char *)&tsPat->program;
 int i = 0;
 for (i = 0; i < tTempNum; ++i)
 {
 TsPatProgram *program = (TsPatProgram *)pTempData;
 if (program->res1 != 0x07)
 {
 printf("XYQ ==> Wrong PmtProgram!\n");
 return -12;
 }

 XTsStream *pTempStream = pXTsStreams + dXStream_PmtIdx; //假定只要一个PMT,多个PMT的后续处理
 pTempStream->mPid = MakeShort(program->programMapPidH, program->programMapPidL);
 pTempStream->mProgram = MakeShort(program->programNumberH, program->programNumberL);
 pTempStream->mType = 0xff;

 pTempData += 4;
 }
 return 0;
}

 if (tsHeader->transportErrorIndicator == 1)
 {
 printf("XYQ ==> transport error !\n");
 return -3;
 }

 if (tsHeader->transportScramblingControl != 0)
 {
 printf("XYQ ==> scrambled faield !\n");
 return -4;
 }

 bool bTempPayloadUnitStartIndicator = tsHeader->payloadUnitStartIndicator == 1 ? true : false;
 bool bTempAdaptationFieldExist = (tsHeader->adaptionFieldControl & 0x02) == 0x02 ? true : false;
 bool bTempPayloadDataExist = (tsHeader->adaptionFieldControl & 0x01) == 0x01 ? true : false;

 unsigned short tTempPid = MakeShort(tsHeader->pidH, tsHeader->pidL);
 //printf("XYQ ==> pid[%d] !\n", tTempPid);
 if (tTempPid != 0x1FFF && bTempPayloadDataExist == true)
 {
 unsigned char *pTempData = (unsigned char *)pInputData;
 pTempData += TS_HEADER_SIZE;
 tInputDataLen -= TS_HEADER_SIZE;
 if (bTempAdaptationFieldExist == true) //存在自适应部分则跳过
 {
 if (tsHeader->adaptionLength > (TS_PACKET_LENGTH - TS_HEADER_SIZE - 1))
 {
 printf("XYQ ==> adaption lenth faield !\n");
 return -5;
 }
 unsigned short adLeng = tsHeader->adaptionLength;
 adLeng += 1;
 pTempData += adLeng;  //包括自身长度
 tInputDataLen -= adLeng; //包括自身长度
 /* printf("adaption length 0x%03d 0x%04d %02x %02x %02x %02x %02x %02x %02x %02x\n", adLeng, tInputDataLen,
 pInputData[0], pInputData[1], pInputData[2], pInputData[3],
 pInputData[4], pInputData[5], pInputData[6], pInputData[7]); */
 }

 if (tTempPid == 0) //PAT
 {
 return XTsDemuxPat(pTempData, tInputDataLen, bTempPayloadUnitStartIndicator);
 }
 else
 {
 XTsStream *pTempPmtStream = pXTsStreams + dXStream_PmtIdx;
 XTsStream *pTempVideoStream = pXTsStreams + dXStream_VideoIdx;
 XTsStream *pTempAudioStream = pXTsStreams + dXStream_AudioIdx;
 if (tTempPid == pTempPmtStream->mPid)
 {
 return XTsDemuxPmt(pTempData, tInputDataLen, bTempPayloadUnitStartIndicator);
 }
 else if (tTempPid == pTempVideoStream->mPid)
 {
 return XTsDemuxPes(pTempData, tInputDataLen, bTempPayloadUnitStartIndicator, pTempVideoStream);
 }
 else if (tTempPid == pTempAudioStream->mPid)
 {
 return XTsDemuxPes(pTempData, tInputDataLen, bTempPayloadUnitStartIndicator, pTempAudioStream);
 }
 else
 {
 printf("XYQ ==> not found Pid !\n");
 return -100;
 }
 }
 }

 return 0;
}

//解析Pmt
static int XTsDemuxPmt(const unsigned char *pTempData, int tInputDataLen, bool bTempPayloadUnitStartIndicator)
{
 if (NULL == pTempData || tInputDataLen < sizeof(TsPmt))
 {
 printf("XYQ ==> pmt input data Error !\n");
 return -1;
 }
 XTsStream *pTempPmtStream = &pXTsStreams[dXStream_PmtIdx];

 TsPmt *tsPmt = (TsPmt *)pTempData;
 if (pTempPmtStream->mType == 0xff) //当mType为0xFF赋值
 {
 if (bTempPayloadUnitStartIndicator)
 {
 if (tsPmt->tableId != 0x02) //pmt表id固定为0x02
 {
 printf("XYQ ==> not pmt table !\n");
 return -13;
 }

 if (tsPmt->reserved_1 != 0x03)
 {
 printf("XYQ ==> pmt data error!\n");
 return -14;
 }
 unsigned short tTempLen = tsPmt->sectionLengthH << 8 | tsPmt->sectionLengthL;
 tTempLen += 4; //PMT内容长度+PMT长度+PMT tableId + 防错码
 if (tTempLen > dXMaxTableLen)
 {
 printf("XYQ ==> pmt data error !\n ");
 return -141;
 }

 XTsTableReset(&tXTsTable, tTempLen);
 unsigned short tTempLL = (tInputDataLen > tTempLen) ? tTempLen : tInputDataLen;

 memcpy(tXTsTable.pData, &(tsPmt->tsHeaderRes), tTempLL);
 tXTsTable.mOffset += tTempLL;
 if (tXTsTable.mOffset < tXTsTable.mLen)
 {
 printf("XYQ ==> pmt wait next part !\n ");
 return 0; // wait next part
 }
 }
 else //PMT table分成多包处理
 {
 if (0 == tXTsTable.mOffset)
 {
 printf("XYQ ==> pmt table not find first !\n ");
 return -142;
 }
 unsigned short tTempL = tXTsTable.mLen - tXTsTable.mOffset;
 unsigned short tTempLL = (tInputDataLen > tTempL) ? tTempL : tInputDataLen;

 memcpy(tXTsTable.pData + tXTsTable.mOffset, pTempData, tTempLL);
 tXTsTable.mOffset += tTempLL;
 if (tXTsTable.mOffset < tXTsTable.mLen)
 {
 printf("XYQ ==> pmt wait next part !\n ");
 return 0; // wait next part
 }
 }
 //处理整包PMT
 tsPmt = (TsPmt *)tXTsTable.pData;
 unsigned short tTempN = MakeShort(tsPmt->programInfoLengthH, tsPmt->programInfoLengthL);
 unsigned short tTempL = tXTsTable.mLen - (13 + 4); //13字节头 + 4字节crc

 if (tTempN > tTempL)
 {
 printf("XYQ ==> pmt pcr Info length Error %d %d!\n %02x %02x %02x %02x %02x %02x %02x %02x", tTempN, tTempL,
    tXTsTable.pData[0], tXTsTable.pData[1], tXTsTable.pData[2], tXTsTable.pData[3],
    tXTsTable.pData[4], tXTsTable.pData[5], tXTsTable.pData[6], tXTsTable.pData[7]);
 return -15;
 }
 //pcr不处理?
 //unsigned short sPcr = MakeShort(tsPmt->pcrPidH, tsPmt->pcrPidL);

 pTempData = (const unsigned char *)(&tsPmt->pmtProgram);
 pTempData += tTempN; //跳过ProgramInfo长度
 tTempL -= tTempN;
 while (tTempL > 0)
 {
 if (tTempL < 5)
 {
 printf("XYQ ==> pmt program length Error, %d!\n ", tTempL);
 return -15;
 }
 TsPmtProgram *program = (TsPmtProgram *)pTempData; //获取一个节目号
 if (program->reseved1 != 0x07)
 {
 printf("XYQ ==> pmt program reseved is not 111 , leftLen[%d]!\n %02x %02x %02x %02x %02x %02x %02x %02x\n",
    tTempL,
    pTempData[0], pTempData[1], pTempData[2], pTempData[3],
    pTempData[4], pTempData[5], pTempData[6], pTempData[7]);
 return -17;
 }

 unsigned short tTempPid = MakeShort(program->elemPidH, program->elemPidL);
 unsigned short tTempLL = MakeShort(program->esLengthH, program->esLengthL) + 5;
 if (tTempLL > tTempL)
 {
 printf("XYQ ==> pmt program esLength Error !\n ");
 return -18;
 }

 pTempData += tTempLL;
 tTempL -= tTempLL;

 // printf("XYQ ==> stream pid : 0x%x 0x%x \n", tTempPid, tTempType);
 XTsStream *pTempStream = NULL;
 int tTempStreamType = XTsGetStreamType(program->streamType);
 if (tTempStreamType == content_type_video)
 {
 pTempStream = &pXTsStreams[dXStream_VideoIdx];
 pTempStream->mContentType = content_type_video;
 }
 else if (tTempStreamType == content_type_audio)
 {
 pTempStream = &pXTsStreams[dXStream_AudioIdx];
 pTempStream->mContentType = content_type_audio;
 }
 else
 {
 continue;
 }

 if (pTempStream && pTempStream->mType != program->streamType)
 {
 pTempStream->mPid = tTempPid;
 pTempStream->mType = program->streamType;
 printf("XYQ ==> stream change type = 0x%02x pid = 0x%04x\n",
    pTempStream->mType, pTempStream->mPid);

 // set es player type
 int tTempCodecType = XTSGetStreamCodecType(pTempStream->mType);
 if (pTempStream->mContentType == content_type_audio) //设置音频类型
 {
 int tTempAudioType = XTSGetStreamAudioType(tTempCodecType);

 if (XXX_EsPlayerSetAcodecType(tTempAudioType) != 0)
 {
 pTempStream->mType = 0xff;
 }
 }
 else if (pTempStream->mContentType == content_type_video) //设置视频类型
 {
 int tTempVideoType = XTSGetStreamVideoType(tTempCodecType);

 if (XXXX_EsPlayerSetVcodecType(tTempVideoType) != 0)
 {
 pTempStream->mType = 0xff;
 }
 }

 printf("XYQ ==> change codec type end !\n");
 }
 else if (pTempStream)
 {
 if (pTempStream->mPid != tTempPid)
 {
 printf("XYQ ==> chamge stream id : 0x%04x 0x%04x \n", pTempStream->mPid, tTempPid);
 }
 pTempStream->mPid = tTempPid;
 }
 }
 }
 else
 {
 printf("XYQ ==> not check pmt table  !\n");
 }

 return 0;
}


//解析Pes
static int TsDemuxPes(const unsigned char *pTempData, int tInputDataLen,
    bool bTempPayloadUnitStartIndicator, XTsStream *pTempStream)
{
 if (NULL == pTempData || NULL == pTempStream)
 {
 printf("XYQ ==> pes input data Error!\n");
 return -1;
 }

 if (bTempPayloadUnitStartIndicator)
 {
 if (tInputDataLen < sizeof(TsPes))
 {
 const unsigned char *pTempData1 = pTempData - 7;
 printf("XYQ ==> pes input data Error, %d %02x %02x %02x %02x %02x %02x %02x %02x !\n",
 tInputDataLen, pTempData1[0], pTempData1[1], pTempData1[2], pTempData1[3],
 pTempData1[4], pTempData1[5], pTempData1[6], pTempData1[7]);
 }
 TsPes *tsPes = (TsPes *)pTempData;
 static const unsigned char tTempStartCodePrefix[] = {0x00, 0x00, 0x01};
 if (memcmp(tsPes->startCode, tTempStartCodePrefix, sizeof(tTempStartCodePrefix)) != 0)
 {
 printf("XYQ ==> pes start Code Error !\n");
 return -21;
 }

 u_int8_t tTempStreamId = tsPes->streamId;
 //unsigned short tTempL = tsPes->pesLengthH << 8 | tsPes->pesLengthL;

 // printf("XYQ ==> stream id = 0x%x \n", tTempStreamId);
 if ((tTempStreamId >= 0xbd && tTempStreamId <= 0xbf) 
 || (tTempStreamId >= 0xc0 && tTempStreamId <= 0xdf) 
 || (tTempStreamId >= 0xe0 && tTempStreamId <= 0xef) 
 || (tTempStreamId >= 0xfa && tTempStreamId <= 0xfe))
 {
 // PES header extension
 unsigned char tTempHLen = tsPes->pesHeaderDataLength + 9;

 if (tInputDataLen < tTempHLen)
 {
 printf("XYQ ==> pes data length Error !\n");
 return -23;
 }

 switch (tsPes->ptsDtsFlags)
 {
 case 0x02: // PTS only
 {
 if (tsPes->pesHeaderDataLength >= 5)
 {
 unsigned char *pPts = (unsigned char *)&tsPes->pesHeaderDataLength;

 u_int64_t tTempPts = XTsDecodePts(pPts + 1);
 //printf("XYQ ==> ptsdts 02 %02d [%lld] %02x %02x %02x %02x %02x !\n", pTempStream->mType,
 // tTempPts, pPts[1], pPts[2], pPts[3], pPts[4], pPts[5]);
 if (pTempStream->mDts > 0 && tTempPts > pTempStream->mDts)
 {
 pTempStream->mFrameRate = tTempPts - pTempStream->mDts;
 }

 pTempStream->mDts = tTempPts;

 if (tTempPts > pTempStream->mLastPts)
 {
 pTempStream->mLastPts = tTempPts;
 }
 else
 {
 //printf("XYQ ==> ptsdts 02 %lld %lld !\n", pTempStream->mLastPts, tTempPts);
 }

 if (0 == pTempStream->mFirstPts && pTempStream->mFrameNum == (pTempStream->mContentType == content_type_video ? 1 : 0))
 {
 pTempStream->mFirstPts = tTempPts;
 }
 pTempStream->mCurPts = tTempPts;
 }
 else
 {
 printf("XYQ ==> pes Header data length Error %d !\n", tsPes->pesHeaderDataLength);
 }
 }
 break;
 case 0x03: // PTS,DTS
 {
 if (tsPes->pesHeaderDataLength >= 10)
 {
 unsigned char *pPts = (unsigned char *)&tsPes->pesHeaderDataLength;
 u_int64_t tTempPts = XTsDecodePts(pPts + 1);
 u_int64_t tTempDts = XTsDecodePts(pPts + 6);
#if 0
 printf("XYQ ==> ptsdts 03 %02d [%lld] [%lld] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x !\n", pTempStream->mType,
 tTempPts, tTempDts, pPts[1], pPts[2], pPts[3], pPts[4], pPts[5],
 pPts[6], pPts[7], pPts[8], pPts[9], pPts[10]);
#endif
 if (pTempStream->mDts > 0 && tTempDts > pTempStream->mDts)
 {
 pTempStream->mFrameRate = tTempDts - pTempStream->mDts;
 }
 pTempStream->mDts = tTempDts;

 if (tTempPts > pTempStream->mLastPts)
 {
 pTempStream->mLastPts = tTempPts;
 }
 else
 {
 //printf("XYQ ==> ptsdts 03 %lld %lld !\n", pTempStream->mLastPts, tTempPts);
 }

 if (!pTempStream->mFirstPts && pTempStream->mFrameNum == (pTempStream->mContentType == content_type_video ? 1 : 0))
 {
 pTempStream->mFirstPts = tTempDts;
 }
 pTempStream->mCurPts = tTempPts;
 }
 else
 {
 printf("XYQ ==> pes Header data length Error %d !\n", tsPes->pesHeaderDataLength);
 }
 }
 break;
 default:
 //printf("XYQ ==> bitmap:%02x\n", tsPes->ptsDtsFlags);
 break;
 }
 // printf("XYQ ==> type : %d, cur pts : %lld  %d \n", pTempStream->mType, (int64_t)pTempVideoStream->mCurPts, (int)(pTempVideoStream->mCurPts/90));
 pTempStream->mStreamId = tTempStreamId;
 pTempStream->mFrameNum++;
 tInputDataLen -= (sizeof(TsPes) + tsPes->pesHeaderDataLength);
 pTempData += (sizeof(TsPes) + tsPes->pesHeaderDataLength);
 }
 else
 {
 printf("XYQ ==> error stream Id:0x%02x\n", tTempStreamId);
 pTempStream->mStreamId = 0;
 }
 }

 if (pTempStream->mStreamId > 0)
 {
 if (tInputDataLen > 0) // play es data
 {
 // printf("XYQ ==> data len : %d \n", tTempDataLen);
 if (bTempPayloadUnitStartIndicator || (pTempStream->mOffset + tInputDataLen) > dXFrameBufLen)
 {
 //printf("XYQ ==> put es data : %d %d \n", bTempPayloadUnitStartIndicator == true ? 1 : 0, pTempStream->mOffset);
 if (pTempStream->mOffset > 0)
 {
 char *pTempTsData = NULL;
 int tTempTsDataLen = 0;
 int tTempRet = 0;
 if (pTempStream->mContentType == content_type_video) //视频数据
 {
 if (1) //pTempStream->mLastPts == pTempStream->mCurPts)
 {
 int bShow = 0;
 do
 {
 tTempRet = XXX_EsPlayerGetBuffer(true, &pTempTsData, &tTempTsDataLen, pTempStream->mOffset);
 if (tTempTsDataLen != pTempStream->mOffset)
 {
 if (bShow == 0)
 {
 printf("XYQ ==> video stream get buf failed : %d %d \n", tTempTsDataLen, pTempStream->mOffset);
 bShow = 1;
 }

 usleep(10);
 }
 else
 {
 break;
 }
 } while (1);

 if (tTempRet == 0)
 {
 memcpy(pTempTsData, pTempStream->pData, tTempTsDataLen);

 unsigned int tTempVideoPts = -1;
 if (pTempStream->mLastPts == pTempStream->mCurPts)
 {
 tTempVideoPts = (unsigned int)(pTempStream->mLastPts / 90);
 }
 tTempVideoPts = 0;
 //printf("XYQ ==>  video pts : %llu, %u \n", pTempStream->mCurPts, tTempVideoPts);
 tTempRet = XXX_EsPlayerPutBuffer(true, tTempTsDataLen, tTempVideoPts);
 if (tTempRet != 0)
 {
 printf("XYQ ==> es player put video buf failed !\n");
 }
 }
 else
 {
 printf("XYQ ==> es player get video buf failed !\n");
 usleep(1000 * 30);
 }
 }
 }
 else if (pTempStream->mContentType == content_type_audio)
 {
 int bShow = 0;
 do
 {
 tTempRet = XXX_EsPlayerGetBuffer(false, &pTempTsData, &tTempTsDataLen, pTempStream->mOffset);
 if (tTempTsDataLen != pTempStream->mOffset)
 {
 if (bShow == 1)
 {
 printf("XYQ ==> audio stream get buf failed : %d %d \n",
 tTempTsDataLen, pTempStream->mOffset);
 bShow = 1;
 }
 usleep(10);
 }
 else
 {
 break;
 }
 } while (1);
 if (tTempRet == 0)
 {
 memcpy(pTempTsData, pTempStream->pData, tTempTsDataLen);
 unsigned int tTempAudioPts = (unsigned int)(pTempStream->mCurPts / 90);
 tTempAudioPts = 0;
 tTempRet = XXXX_EsPlayerPutBuffer(false, tTempTsDataLen, tTempAudioPts);
 if (tTempRet != 0)
 {
 printf("XYQ ==> es player put audio buf failed !\n");
 }
 }
 else
 {
 printf("XYQ ==> es player get audio buf failed !\n");
 usleep(1000 * 30);
 }
 }
 }
 pTempStream->mOffset = 0;
 }
 //拷贝完后把数据写入缓存
 if (pTempStream->mOffset + tInputDataLen < dXFrameBufLen)
 {
 memcpy(pTempStream->pData + pTempStream->mOffset, pTempData, tInputDataLen);
 pTempStream->mOffset += tInputDataLen;
 }
 }
 /*
 int tTempFd = pTempStream->mFile;
 if (tTempFd < 0)
 {
 if (pTempStream->mContentType == content_type_audio)
 {
 tTempFd = open("./audio.es", O_CREAT | O_RDWR | O_TRUNC, 0777);
 }
 else if (pTempStream->mContentType == content_type_video)
 {
 tTempFd = open("./video.es", O_CREAT | O_RDWR | O_TRUNC, 0777);
 }
 pTempStream->mFile = tTempFd;
 }

 if (tTempFd > 0)
 {
 int tTempWriteLen = write(tTempFd, pTempData, tInputDataLen);
 printf("XYQ ==> write len : %d  %d \n", tTempWriteLen, tInputDataLen);
 }
 */
 }
 else
 {
 printf("XYQ ==> es streamId is 0!\n");
 }

 return 0;
}


标签: c++ TS PES iso13818-1

评论(0) 浏览(4318)

vmware回收ubuntu内存

2020-5-14

1. 进入ubuntu虚拟机

cat /dev/zero > zero.fill

sync

sleep 1

sync

rm -f zero.fill

2. 回到宿主机执行

vmware-vdiskmanager.exe -k 虚拟机.vmdk


标签: vmware ubuntu

评论(0) 浏览(2573)

Powered by EMLOG Copyright @ 深圳市炽旗科技 版权所有. 闽ICP备14012694号-2